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/06/30 07:35:19 UTC

[2/6] [OLINGO-317] Refactoring of 'Value-classes'

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a2874142/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java
index 74a76ad..57a45f6 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java
@@ -30,16 +30,18 @@ import javax.xml.stream.XMLStreamWriter;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.olingo.commons.api.Constants;
 import org.apache.olingo.commons.api.data.Annotation;
-import org.apache.olingo.commons.api.data.CollectionValue;
 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.LinkedComplexValue;
 import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.data.ResWrap;
-import org.apache.olingo.commons.api.data.Value;
+import org.apache.olingo.commons.api.data.ValueType;
 import org.apache.olingo.commons.api.domain.ODataOperation;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.apache.olingo.commons.api.edm.geo.Geospatial;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.commons.api.serialization.ODataSerializer;
 import org.apache.olingo.commons.api.serialization.ODataSerializerException;
@@ -48,6 +50,7 @@ import org.apache.olingo.commons.core.data.EntityImpl;
 import org.apache.olingo.commons.core.data.EntitySetImpl;
 import org.apache.olingo.commons.core.data.LinkImpl;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
 
 import com.fasterxml.aalto.stax.OutputFactoryImpl;
 
@@ -69,8 +72,10 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
     this.serverMode = serverMode;
   }
 
-  private void collection(final XMLStreamWriter writer, final CollectionValue value) throws XMLStreamException {
-    for (Value item : value.get()) {
+  private void collection(final XMLStreamWriter writer,
+      final ValueType valueType, final EdmPrimitiveTypeKind kind, final List<?> value)
+          throws XMLStreamException, EdmPrimitiveTypeException {
+    for (Object item : value) {
       if (version.compareTo(ODataServiceVersion.V40) < 0) {
         writer.writeStartElement(Constants.PREFIX_DATASERVICES, Constants.ELEM_ELEMENT,
             version.getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES));
@@ -78,29 +83,54 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
         writer.writeStartElement(Constants.PREFIX_METADATA, Constants.ELEM_ELEMENT,
             version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA));
       }
-      value(writer, item);
+      value(writer, valueType, kind, item);
       writer.writeEndElement();
     }
   }
 
-  private void value(final XMLStreamWriter writer, final Value value) throws XMLStreamException {
-    if (value.isPrimitive()) {
-      writer.writeCharacters(value.asPrimitive().get());
-    } else if (value.isEnum()) {
-      writer.writeCharacters(value.asEnum().get());
-    } else if (value.isGeospatial()) {
-      this.geoSerializer.serialize(writer, value.asGeospatial().get());
-    } else if (value.isCollection()) {
-      collection(writer, value.asCollection());
-    } else if (value.isComplex()) {
-      for (Property property : value.asComplex().get()) {
+  @SuppressWarnings("unchecked")
+  private void value(final XMLStreamWriter writer,
+      final ValueType valueType, final EdmPrimitiveTypeKind kind, final Object value)
+          throws XMLStreamException, EdmPrimitiveTypeException {
+    if (value == null) {
+      writer.writeAttribute(Constants.PREFIX_METADATA, version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
+          Constants.ATTR_NULL, Boolean.TRUE.toString());
+      return;
+    }
+    switch (valueType) {
+    case PRIMITIVE:
+      writer.writeCharacters(kind == null ? value.toString() :
+          EdmPrimitiveTypeFactory.getInstance(kind)  // TODO: add facets
+              .valueToString(value, null, null, Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null));
+      break;
+    case ENUM:
+      writer.writeCharacters(value.toString());
+      break;
+    case GEOSPATIAL:
+      this.geoSerializer.serialize(writer, (Geospatial) value);
+      break;
+    case COLLECTION_PRIMITIVE:
+    case COLLECTION_GEOSPATIAL:
+    case COLLECTION_ENUM:
+    case COLLECTION_COMPLEX:
+    case COLLECTION_LINKED_COMPLEX:
+      collection(writer, valueType.getBaseType(), kind, (List<?>) value);
+      break;
+    case LINKED_COMPLEX:
+      for (Property property : ((LinkedComplexValue) value).getValue()) {
+        property(writer, property, false);
+      }
+      break;
+    case COMPLEX:
+      for (Property property : (List<Property>) value) {
         property(writer, property, false);
       }
+      break;
     }
   }
 
   public void property(final XMLStreamWriter writer, final Property property, final boolean standalone)
-      throws XMLStreamException {
+      throws XMLStreamException, EdmPrimitiveTypeException {
 
     if (version.compareTo(ODataServiceVersion.V40) >= 0 && standalone) {
       writer.writeStartElement(Constants.PREFIX_METADATA, Constants.VALUE,
@@ -114,23 +144,20 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
       namespaces(writer);
     }
 
+    EdmTypeInfo typeInfo = null;
     if (StringUtils.isNotBlank(property.getType())) {
-      final EdmTypeInfo typeInfo = new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
+      typeInfo = new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
       if (!EdmPrimitiveTypeKind.String.getFullQualifiedName().toString().equals(typeInfo.internal())) {
         writer.writeAttribute(Constants.PREFIX_METADATA, version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
             Constants.ATTR_TYPE, typeInfo.external(version));
       }
     }
 
-    if (property.getValue().isNull()) {
-      writer.writeAttribute(Constants.PREFIX_METADATA, version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
-          Constants.ATTR_NULL, Boolean.TRUE.toString());
-    } else {
-      value(writer, property.getValue());
-      if (property.getValue().isLinkedComplex()) {
-        links(writer, property.getValue().asLinkedComplex().getAssociationLinks());
-        links(writer, property.getValue().asLinkedComplex().getNavigationLinks());
-      }
+    value(writer, property.getValueType(), typeInfo == null ? null : typeInfo.getPrimitiveTypeKind(),
+        property.getValue());
+    if (!property.isNull() && property.isLinkedComplex()) {
+      links(writer, property.asLinkedComplex().getAssociationLinks());
+      links(writer, property.asLinkedComplex().getNavigationLinks());
     }
 
     writer.writeEndElement();
@@ -140,7 +167,8 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
     }
   }
 
-  private void property(final XMLStreamWriter writer, final Property property) throws XMLStreamException {
+  private void property(final XMLStreamWriter writer, final Property property)
+      throws XMLStreamException, EdmPrimitiveTypeException {
     property(writer, property, true);
   }
 
@@ -153,7 +181,8 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
     namespaces(writer);
   }
 
-  private void property(final Writer outWriter, final Property property) throws XMLStreamException {
+  private void property(final Writer outWriter, final Property property)
+      throws XMLStreamException, EdmPrimitiveTypeException {
     final XMLStreamWriter writer = FACTORY.createXMLStreamWriter(outWriter);
 
     writer.writeStartDocument();
@@ -164,7 +193,8 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
     writer.flush();
   }
 
-  private void links(final XMLStreamWriter writer, final List<Link> links) throws XMLStreamException {
+  private void links(final XMLStreamWriter writer, final List<Link> links)
+      throws XMLStreamException, EdmPrimitiveTypeException {
     for (Link link : links) {
       writer.writeStartElement(Constants.ATOM_ELEM_LINK);
 
@@ -216,14 +246,15 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
     }
   }
 
-  private void properties(final XMLStreamWriter writer, final List<Property> properties) throws XMLStreamException {
+  private void properties(final XMLStreamWriter writer, final List<Property> properties)
+      throws XMLStreamException, EdmPrimitiveTypeException {
     for (Property property : properties) {
       property(writer, property, false);
     }
   }
 
   private void annotation(final XMLStreamWriter writer, final Annotation annotation, final String target)
-      throws XMLStreamException {
+      throws XMLStreamException, EdmPrimitiveTypeException {
 
     writer.writeStartElement(Constants.PREFIX_METADATA, Constants.ANNOTATION,
         version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA));
@@ -234,25 +265,23 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
       writer.writeAttribute(Constants.ATTR_TARGET, target);
     }
 
+    EdmTypeInfo typeInfo = null;
     if (StringUtils.isNotBlank(annotation.getType())) {
-      final EdmTypeInfo typeInfo = new EdmTypeInfo.Builder().setTypeExpression(annotation.getType()).build();
+      typeInfo = new EdmTypeInfo.Builder().setTypeExpression(annotation.getType()).build();
       if (!EdmPrimitiveTypeKind.String.getFullQualifiedName().toString().equals(typeInfo.internal())) {
         writer.writeAttribute(Constants.PREFIX_METADATA, version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
             Constants.ATTR_TYPE, typeInfo.external(version));
       }
     }
 
-    if (annotation.getValue().isNull()) {
-      writer.writeAttribute(Constants.PREFIX_METADATA, version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
-          Constants.ATTR_NULL, Boolean.TRUE.toString());
-    } else {
-      value(writer, annotation.getValue());
-    }
+    value(writer, annotation.getValueType(), typeInfo == null ? null : typeInfo.getPrimitiveTypeKind(),
+        annotation.getValue());
 
     writer.writeEndElement();
   }
 
-  private void entity(final XMLStreamWriter writer, final Entity entity) throws XMLStreamException {
+  private void entity(final XMLStreamWriter writer, final Entity entity)
+      throws XMLStreamException, EdmPrimitiveTypeException {
     if (entity.getBaseURI() != null) {
       writer.writeAttribute(XMLConstants.XML_NS_URI, Constants.ATTR_XML_BASE, entity.getBaseURI().toASCIIString());
     }
@@ -344,7 +373,8 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
     writer.writeAttribute(Constants.ATOM_ATTR_ID, container.getPayload().getId().toASCIIString());
   }
 
-  private void entity(final Writer outWriter, final Entity entity) throws XMLStreamException {
+  private void entity(final Writer outWriter, final Entity entity)
+      throws XMLStreamException, EdmPrimitiveTypeException {
     final XMLStreamWriter writer = FACTORY.createXMLStreamWriter(outWriter);
 
     if (entity.getType() == null && entity.getProperties().isEmpty()) {
@@ -363,7 +393,8 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
     writer.flush();
   }
 
-  private void entity(final Writer outWriter, final ResWrap<Entity> container) throws XMLStreamException {
+  private void entity(final Writer outWriter, final ResWrap<Entity> container)
+      throws XMLStreamException, EdmPrimitiveTypeException {
     final Entity entity = container.getPayload();
 
     final XMLStreamWriter writer = FACTORY.createXMLStreamWriter(outWriter);
@@ -386,7 +417,8 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
     writer.flush();
   }
 
-  private void entitySet(final XMLStreamWriter writer, final EntitySet entitySet) throws XMLStreamException {
+  private void entitySet(final XMLStreamWriter writer, final EntitySet entitySet)
+      throws XMLStreamException, EdmPrimitiveTypeException {
     if (entitySet.getBaseURI() != null) {
       writer.writeAttribute(XMLConstants.XML_NS_URI, Constants.ATTR_XML_BASE, entitySet.getBaseURI().toASCIIString());
     }
@@ -437,7 +469,8 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
     }
   }
 
-  private void entitySet(final Writer outWriter, final EntitySet entitySet) throws XMLStreamException {
+  private void entitySet(final Writer outWriter, final EntitySet entitySet)
+      throws XMLStreamException, EdmPrimitiveTypeException {
     final XMLStreamWriter writer = FACTORY.createXMLStreamWriter(outWriter);
 
     startDocument(writer, Constants.ATOM_ELEM_FEED);
@@ -449,7 +482,8 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
     writer.flush();
   }
 
-  private void entitySet(final Writer outWriter, final ResWrap<EntitySet> entitySet) throws XMLStreamException {
+  private void entitySet(final Writer outWriter, final ResWrap<EntitySet> entitySet)
+      throws XMLStreamException, EdmPrimitiveTypeException {
     final XMLStreamWriter writer = FACTORY.createXMLStreamWriter(outWriter);
 
     startDocument(writer, Constants.ATOM_ELEM_FEED);
@@ -494,6 +528,8 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
       }
     } catch (final XMLStreamException e) {
       throw new ODataSerializerException(e);
+    } catch (final EdmPrimitiveTypeException e) {
+      throw new ODataSerializerException(e);
     }
   }
 
@@ -513,6 +549,8 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
       }
     } catch (final XMLStreamException e) {
       throw new ODataSerializerException(e);
+    } catch (final EdmPrimitiveTypeException e) {
+      throw new ODataSerializerException(e);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a2874142/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeserializer.java
index bb2e0d2..d52a87c 100755
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeserializer.java
@@ -21,6 +21,7 @@ package org.apache.olingo.commons.core.serialization;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -33,32 +34,28 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.olingo.commons.api.Constants;
 import org.apache.olingo.commons.api.data.Annotatable;
 import org.apache.olingo.commons.api.data.Annotation;
-import org.apache.olingo.commons.api.data.CollectionValue;
-import org.apache.olingo.commons.api.data.ComplexValue;
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntitySet;
 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.data.ResWrap;
 import org.apache.olingo.commons.api.data.Valuable;
-import org.apache.olingo.commons.api.data.Value;
+import org.apache.olingo.commons.api.data.ValueType;
 import org.apache.olingo.commons.api.domain.ODataError;
 import org.apache.olingo.commons.api.domain.ODataLinkType;
 import org.apache.olingo.commons.api.domain.ODataPropertyType;
+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.constants.ODataServiceVersion;
+import org.apache.olingo.commons.api.edm.geo.Geospatial;
 import org.apache.olingo.commons.api.serialization.ODataDeserializer;
 import org.apache.olingo.commons.api.serialization.ODataDeserializerException;
 import org.apache.olingo.commons.core.data.AnnotationImpl;
-import org.apache.olingo.commons.core.data.CollectionValueImpl;
-import org.apache.olingo.commons.core.data.ComplexValueImpl;
 import org.apache.olingo.commons.core.data.EntitySetImpl;
-import org.apache.olingo.commons.core.data.EnumValueImpl;
-import org.apache.olingo.commons.core.data.GeospatialValueImpl;
 import org.apache.olingo.commons.core.data.LinkImpl;
 import org.apache.olingo.commons.core.data.LinkedComplexValueImpl;
-import org.apache.olingo.commons.core.data.NullValueImpl;
-import org.apache.olingo.commons.core.data.PrimitiveValueImpl;
 import org.apache.olingo.commons.core.data.PropertyImpl;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
 
@@ -115,7 +112,7 @@ public class JsonDeserializer implements ODataDeserializer {
     jsonNextLink = version.getJSONMap().get(ODataServiceVersion.JSON_NEXT_LINK);
     jsonDeltaLink = version.getJSONMap().get(ODataServiceVersion.JSON_DELTA_LINK);
     jsonError = version.getJSONMap().get(ODataServiceVersion.JSON_ERROR);
-}
+  }
 
   private JsonGeoValueDeserializer getGeoDeserializer() {
     if (geoDeserializer == null) {
@@ -274,7 +271,8 @@ public class JsonDeserializer implements ODataDeserializer {
   }
 
   protected void populate(final Annotatable annotatable, final List<Property> properties,
-      final ObjectNode tree, final ObjectCodec codec) throws IOException {
+      final ObjectNode tree, final ObjectCodec codec)
+          throws IOException, EdmPrimitiveTypeException {
 
     String type = null;
     Annotation annotation = null;
@@ -315,96 +313,92 @@ public class JsonDeserializer implements ODataDeserializer {
     }
   }
 
-  private Value fromPrimitive(final JsonNode node, final EdmTypeInfo typeInfo) {
-    final Value value;
-
-    if (node.isNull()) {
-      value = new NullValueImpl();
-    } else {
-      if (typeInfo != null && typeInfo.getPrimitiveTypeKind().isGeospatial()) {
-        value = new GeospatialValueImpl(getGeoDeserializer().deserialize(node, typeInfo));
-      } else {
-        value = new PrimitiveValueImpl(node.asText());
-      }
-    }
-
-    return value;
+  private Object fromPrimitive(final JsonNode node, final EdmTypeInfo typeInfo) throws EdmPrimitiveTypeException {
+    return node.isNull() ? null :
+        typeInfo == null ? node.asText() :
+            typeInfo.getPrimitiveTypeKind().isGeospatial() ?
+                getGeoDeserializer().deserialize(node, typeInfo) :
+                ((EdmPrimitiveType) typeInfo.getType())
+                    .valueOfString(node.asText(), true, null,
+                        Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, true,
+                        ((EdmPrimitiveType) typeInfo.getType()).getDefaultType());
   }
 
-  private ComplexValue fromComplex(final ObjectNode node, final ObjectCodec codec) throws IOException {
-    final ComplexValue value = version.compareTo(ODataServiceVersion.V40) < 0
-        ? new ComplexValueImpl()
-        : new LinkedComplexValueImpl();
+  private Object fromComplex(final ObjectNode node, final ObjectCodec codec)
+      throws IOException, EdmPrimitiveTypeException {
+    final Object value = version.compareTo(ODataServiceVersion.V40) < 0 ?
+        new ArrayList<Property>() :
+        new LinkedComplexValueImpl();
 
-    if (value.isLinkedComplex()) {
+    if (value instanceof LinkedComplexValue) {
       final Set<String> toRemove = new HashSet<String>();
       for (final Iterator<Map.Entry<String, JsonNode>> itor = node.fields(); itor.hasNext();) {
         final Map.Entry<String, JsonNode> field = itor.next();
 
-        links(field, value.asLinkedComplex(), toRemove, node, codec);
+        links(field, (LinkedComplexValue) value, toRemove, node, codec);
       }
       node.remove(toRemove);
-    }
 
-    populate(value.asLinkedComplex(), value.get(), node, codec);
+      populate((LinkedComplexValue) value, ((LinkedComplexValue) value).getValue(), node, codec);
+    } else {
+      populate(null, (List<Property>) value, node, codec);
+    }
 
     return value;
   }
 
-  private CollectionValue fromCollection(final Iterator<JsonNode> nodeItor, final EdmTypeInfo typeInfo,
-      final ObjectCodec codec) throws IOException {
+  private void fromCollection(Valuable valuable, final Iterator<JsonNode> nodeItor, final EdmTypeInfo typeInfo,
+      final ObjectCodec codec) throws IOException, EdmPrimitiveTypeException {
 
-    final CollectionValueImpl value = new CollectionValueImpl();
+    List<Object> values = new ArrayList<Object>();
+    ValueType valueType = ValueType.COLLECTION_PRIMITIVE;
 
-    final EdmTypeInfo type = typeInfo == null
-        ? null
-        : new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
+    final EdmTypeInfo type = typeInfo == null ? null :
+        new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
 
     while (nodeItor.hasNext()) {
       final JsonNode child = nodeItor.next();
 
       if (child.isValueNode()) {
         if (typeInfo == null || typeInfo.isPrimitiveType()) {
-          value.get().add(fromPrimitive(child, type));
+          final Object value = fromPrimitive(child, type);
+          valueType = value instanceof Geospatial ? ValueType.COLLECTION_GEOSPATIAL : ValueType.COLLECTION_PRIMITIVE;
+          values.add(value);
         } else {
-          value.get().add(new EnumValueImpl(child.asText()));
+          valueType = ValueType.COLLECTION_ENUM;
+          values.add(child.asText());
         }
       } else if (child.isContainerNode()) {
         if (child.has(jsonType)) {
           ((ObjectNode) child).remove(jsonType);
         }
-        value.get().add(fromComplex((ObjectNode) child, codec));
+        final Object value = fromComplex((ObjectNode) child, codec);
+        valueType = value instanceof LinkedComplexValue ? ValueType.COLLECTION_LINKED_COMPLEX :
+            ValueType.COLLECTION_COMPLEX;
+        values.add(value);
       }
     }
-
-    return value;
+    valuable.setValue(valueType, values);
   }
 
   protected void value(final Valuable valuable, final JsonNode node, final ObjectCodec codec)
-      throws IOException {
-
-    EdmTypeInfo typeInfo = StringUtils.isBlank(valuable.getType())
-        ? null
-        : new EdmTypeInfo.Builder().setTypeExpression(valuable.getType()).build();
+      throws IOException, EdmPrimitiveTypeException {
+    EdmTypeInfo typeInfo = StringUtils.isBlank(valuable.getType()) ? null :
+        new EdmTypeInfo.Builder().setTypeExpression(valuable.getType()).build();
 
     final Map.Entry<ODataPropertyType, EdmTypeInfo> guessed = guessPropertyType(node);
     if (typeInfo == null) {
       typeInfo = guessed.getValue();
     }
 
-    final ODataPropertyType propType = typeInfo == null
-        ? guessed.getKey()
-        : typeInfo.isCollection()
-            ? ODataPropertyType.COLLECTION
-            : typeInfo.isPrimitiveType()
-                ? ODataPropertyType.PRIMITIVE
-                : node.isValueNode()
-                    ? ODataPropertyType.ENUM
-                    : ODataPropertyType.COMPLEX;
+    final ODataPropertyType propType = typeInfo == null ? guessed.getKey() :
+        typeInfo.isCollection() ? ODataPropertyType.COLLECTION :
+            typeInfo.isPrimitiveType() ? ODataPropertyType.PRIMITIVE :
+                node.isValueNode() ? ODataPropertyType.ENUM : ODataPropertyType.COMPLEX;
 
     switch (propType) {
     case COLLECTION:
-      valuable.setValue(fromCollection(node.elements(), typeInfo, codec));
+      fromCollection(valuable, node.elements(), typeInfo, codec);
       break;
 
     case COMPLEX:
@@ -412,23 +406,26 @@ public class JsonDeserializer implements ODataDeserializer {
         valuable.setType(node.get(jsonType).asText());
         ((ObjectNode) node).remove(jsonType);
       }
-      valuable.setValue(fromComplex((ObjectNode) node, codec));
+      final Object value = fromComplex((ObjectNode) node, codec);
+      valuable.setValue(value instanceof LinkedComplexValue ? ValueType.LINKED_COMPLEX : ValueType.COMPLEX, value);
       break;
 
     case ENUM:
-      valuable.setValue(new EnumValueImpl(node.asText()));
+      valuable.setValue(ValueType.ENUM, node.asText());
       break;
 
     case PRIMITIVE:
       if (valuable.getType() == null && typeInfo != null) {
         valuable.setType(typeInfo.getFullQualifiedName().toString());
       }
-      valuable.setValue(fromPrimitive(node, typeInfo));
+      final Object primitiveValue = fromPrimitive(node, typeInfo);
+      valuable.setValue(primitiveValue instanceof Geospatial ? ValueType.GEOSPATIAL : ValueType.PRIMITIVE,
+          primitiveValue);
       break;
 
     case EMPTY:
     default:
-      valuable.setValue(new PrimitiveValueImpl(StringUtils.EMPTY));
+      valuable.setValue(ValueType.PRIMITIVE, StringUtils.EMPTY);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a2874142/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntityDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntityDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntityDeserializer.java
index af5d42f..ca60fbe 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntityDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntityDeserializer.java
@@ -37,6 +37,7 @@ import org.apache.olingo.commons.api.data.Link;
 import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.domain.ODataLinkType;
 import org.apache.olingo.commons.api.domain.ODataOperation;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 import org.apache.olingo.commons.core.data.AnnotationImpl;
 import org.apache.olingo.commons.core.data.EntityImpl;
@@ -188,7 +189,11 @@ public class JsonEntityDeserializer extends JsonDeserializer {
       } else if (customAnnotation.matches() && !"odata".equals(customAnnotation.group(2))) {
         final Annotation annotation = new AnnotationImpl();
         annotation.setTerm(customAnnotation.group(2) + "." + customAnnotation.group(3));
-        value(annotation, field.getValue(), parser.getCodec());
+        try {
+          value(annotation, field.getValue(), parser.getCodec());
+        } catch (final EdmPrimitiveTypeException e) {
+          throw new IOException(e);
+        }
 
         if (!annotations.containsKey(customAnnotation.group(1))) {
           annotations.put(customAnnotation.group(1), new ArrayList<Annotation>());
@@ -216,7 +221,11 @@ public class JsonEntityDeserializer extends JsonDeserializer {
 
     tree.remove(toRemove);
 
-    populate(entity, entity.getProperties(), tree, parser.getCodec());
+    try {
+      populate(entity, entity.getProperties(), tree, parser.getCodec());
+    } catch (final EdmPrimitiveTypeException e) {
+      throw new IOException(e);
+    }
 
     return new ResWrap<Entity>(contextURL, metadataETag, entity);
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a2874142/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java
index 22d6a92..c49bb4f 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java
@@ -29,6 +29,7 @@ import org.apache.olingo.commons.api.data.Link;
 import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.domain.ODataOperation;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
 
@@ -43,12 +44,13 @@ public class JsonEntitySerializer extends JsonSerializer {
     super(version, serverMode);
   }
 
-  protected void doSerialize(final Entity entity, final JsonGenerator jgen) throws IOException {
+  protected void doSerialize(final Entity entity, final JsonGenerator jgen)
+      throws IOException, EdmPrimitiveTypeException {
     doContainerSerialize(new ResWrap<Entity>((URI) null, null, entity), jgen);
   }
 
   protected void doContainerSerialize(final ResWrap<Entity> container, final JsonGenerator jgen)
-      throws IOException {
+      throws IOException, EdmPrimitiveTypeException {
 
     final Entity entity = container.getPayload();
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a2874142/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetDeserializer.java
index d7f86fb..d7dfc8b 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetDeserializer.java
@@ -28,6 +28,7 @@ import org.apache.olingo.commons.api.Constants;
 import org.apache.olingo.commons.api.data.Annotation;
 import org.apache.olingo.commons.api.data.EntitySet;
 import org.apache.olingo.commons.api.data.ResWrap;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 import org.apache.olingo.commons.core.data.AnnotationImpl;
 import org.apache.olingo.commons.core.data.EntitySetImpl;
@@ -108,7 +109,11 @@ public class JsonEntitySetDeserializer extends JsonDeserializer {
         final Annotation annotation = new AnnotationImpl();
         annotation.setTerm(field.getKey().substring(1));
 
-        value(annotation, field.getValue(), parser.getCodec());
+        try {
+          value(annotation, field.getValue(), parser.getCodec());
+        } catch (final EdmPrimitiveTypeException e) {
+          throw new IOException(e);
+        }
         entitySet.getAnnotations().add(annotation);
       }
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a2874142/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetSerializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetSerializer.java
index e1cc38b..dadf87a 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetSerializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetSerializer.java
@@ -27,6 +27,7 @@ import org.apache.olingo.commons.api.data.Annotation;
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntitySet;
 import org.apache.olingo.commons.api.data.ResWrap;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 
 import com.fasterxml.jackson.core.JsonGenerator;
@@ -37,12 +38,13 @@ public class JsonEntitySetSerializer extends JsonSerializer {
     super(version, serverMode);
   }
 
-  protected void doSerialize(final EntitySet entitySet, final JsonGenerator jgen) throws IOException {
+  protected void doSerialize(final EntitySet entitySet, final JsonGenerator jgen)
+      throws IOException, EdmPrimitiveTypeException {
     doContainerSerialize(new ResWrap<EntitySet>((URI) null, null, entitySet), jgen);
   }
 
   protected void doContainerSerialize(final ResWrap<EntitySet> container, final JsonGenerator jgen)
-      throws IOException {
+      throws IOException, EdmPrimitiveTypeException {
 
     final EntitySet entitySet = container.getPayload();
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a2874142/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertyDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertyDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertyDeserializer.java
index 380d245..4e77825 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertyDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertyDeserializer.java
@@ -28,9 +28,10 @@ import org.apache.olingo.commons.api.Constants;
 import org.apache.olingo.commons.api.data.Annotation;
 import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.data.ResWrap;
+import org.apache.olingo.commons.api.data.ValueType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 import org.apache.olingo.commons.core.data.AnnotationImpl;
-import org.apache.olingo.commons.core.data.NullValueImpl;
 import org.apache.olingo.commons.core.data.PropertyImpl;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
 
@@ -81,12 +82,16 @@ public class JsonPropertyDeserializer extends JsonDeserializer {
     }
 
     if (tree.has(Constants.JSON_NULL) && tree.get(Constants.JSON_NULL).asBoolean()) {
-      property.setValue(new NullValueImpl());
+      property.setValue(ValueType.PRIMITIVE, null);
       tree.remove(Constants.JSON_NULL);
     }
 
     if (property.getValue() == null) {
-      value(property, tree.has(Constants.VALUE) ? tree.get(Constants.VALUE) : tree, parser.getCodec());
+      try {
+        value(property, tree.has(Constants.VALUE) ? tree.get(Constants.VALUE) : tree, parser.getCodec());
+      } catch (final EdmPrimitiveTypeException e) {
+        throw new IOException(e);
+      }
       tree.remove(Constants.VALUE);
     }
 
@@ -97,7 +102,11 @@ public class JsonPropertyDeserializer extends JsonDeserializer {
         final Annotation annotation = new AnnotationImpl();
         annotation.setTerm(field.getKey().substring(1));
 
-        value(annotation, field.getValue(), parser.getCodec());
+        try {
+          value(annotation, field.getValue(), parser.getCodec());
+        } catch (final EdmPrimitiveTypeException e) {
+          throw new IOException(e);
+        }
         property.getAnnotations().add(annotation);
       }
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a2874142/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java
index 9576007..667b91f 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java
@@ -26,6 +26,7 @@ import org.apache.olingo.commons.api.Constants;
 import org.apache.olingo.commons.api.data.Annotation;
 import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.data.ResWrap;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
 
@@ -40,12 +41,13 @@ public class JsonPropertySerializer extends JsonSerializer {
     super(version, serverMode);
   }
 
-  protected void doSerialize(final Property property, final JsonGenerator jgen) throws IOException {
+  protected void doSerialize(final Property property, final JsonGenerator jgen)
+      throws IOException, EdmPrimitiveTypeException {
     doContainerSerialize(new ResWrap<Property>((URI) null, null, property), jgen);
   }
 
   protected void doContainerSerialize(final ResWrap<Property> container, final JsonGenerator jgen)
-          throws IOException {
+          throws IOException, EdmPrimitiveTypeException {
 
     final Property property = container.getPayload();
 
@@ -66,21 +68,25 @@ public class JsonPropertySerializer extends JsonSerializer {
       valuable(jgen, annotation, "@" + annotation.getTerm());
     }
 
-    if (property.getValue().isNull()) {
+    if (property.isNull()) {
       jgen.writeBooleanField(Constants.JSON_NULL, true);
-    } else if (property.getValue().isPrimitive()) {
+    } else if (property.isPrimitive()) {
       final EdmTypeInfo typeInfo = property.getType() == null
               ? null
               : new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
 
       jgen.writeFieldName(Constants.VALUE);
-      primitiveValue(jgen, typeInfo, property.getValue().asPrimitive());
-    } else if (property.getValue().isEnum()) {
-      jgen.writeStringField(Constants.VALUE, property.getValue().asEnum().get());
-    } else if (property.getValue().isGeospatial() || property.getValue().isCollection()) {
+      primitiveValue(jgen, typeInfo, property.asPrimitive());
+    } else if (property.isEnum()) {
+      jgen.writeStringField(Constants.VALUE, property.asEnum().toString());
+    } else if (property.isGeospatial() || property.isCollection()) {
       valuable(jgen, property, Constants.VALUE);
-    } else if (property.getValue().isComplex()) {
-      for (Property cproperty : property.getValue().asComplex().get()) {
+    } else if (property.isLinkedComplex()) {
+      for (Property cproperty : property.asLinkedComplex().getValue()) {
+        valuable(jgen, cproperty, cproperty.getName());
+      }
+    } else if (property.isComplex()) {
+      for (Property cproperty : property.asComplex()) {
         valuable(jgen, cproperty, cproperty.getName());
       }
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a2874142/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java
index 39b2d65..aefd8a0 100755
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java
@@ -26,28 +26,28 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.math.NumberUtils;
 import org.apache.olingo.commons.api.Constants;
 import org.apache.olingo.commons.api.data.Annotatable;
 import org.apache.olingo.commons.api.data.Annotation;
-import org.apache.olingo.commons.api.data.CollectionValue;
 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.PrimitiveValue;
+import org.apache.olingo.commons.api.data.LinkedComplexValue;
 import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.data.Valuable;
-import org.apache.olingo.commons.api.data.Value;
+import org.apache.olingo.commons.api.data.ValueType;
 import org.apache.olingo.commons.api.domain.ODataLinkType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.apache.olingo.commons.api.edm.geo.Geospatial;
 import org.apache.olingo.commons.api.serialization.ODataSerializer;
 import org.apache.olingo.commons.api.serialization.ODataSerializerException;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
 
 import com.fasterxml.jackson.core.JsonFactory;
 import com.fasterxml.jackson.core.JsonGenerator;
@@ -58,10 +58,10 @@ public class JsonSerializer implements ODataSerializer {
   protected boolean serverMode;
 
   private static final EdmPrimitiveTypeKind[] NUMBER_TYPES = {
-    EdmPrimitiveTypeKind.Byte, EdmPrimitiveTypeKind.SByte,
-    EdmPrimitiveTypeKind.Single, EdmPrimitiveTypeKind.Double,
-    EdmPrimitiveTypeKind.Int16, EdmPrimitiveTypeKind.Int32, EdmPrimitiveTypeKind.Int64,
-    EdmPrimitiveTypeKind.Decimal
+      EdmPrimitiveTypeKind.Byte, EdmPrimitiveTypeKind.SByte,
+      EdmPrimitiveTypeKind.Single, EdmPrimitiveTypeKind.Double,
+      EdmPrimitiveTypeKind.Int16, EdmPrimitiveTypeKind.Int32, EdmPrimitiveTypeKind.Int64,
+      EdmPrimitiveTypeKind.Decimal
   };
 
   private final JsonGeoValueSerializer geoSerializer = new JsonGeoValueSerializer();
@@ -87,6 +87,8 @@ public class JsonSerializer implements ODataSerializer {
       json.flush();
     } catch (final IOException e) {
       throw new ODataSerializerException(e);
+    } catch (final EdmPrimitiveTypeException e) {
+      throw new ODataSerializerException(e);
     }
   }
 
@@ -108,6 +110,8 @@ public class JsonSerializer implements ODataSerializer {
       json.flush();
     } catch (final IOException e) {
       throw new ODataSerializerException(e);
+    } catch (final EdmPrimitiveTypeException e) {
+      throw new ODataSerializerException(e);
     }
   }
 
@@ -117,7 +121,8 @@ public class JsonSerializer implements ODataSerializer {
     jgen.writeEndObject();
   }
 
-  protected void links(final Linked linked, final JsonGenerator jgen) throws IOException {
+  protected void links(final Linked linked, final JsonGenerator jgen)
+      throws IOException, EdmPrimitiveTypeException {
     if (serverMode) {
       serverLinks(linked, jgen);
     } else {
@@ -125,7 +130,8 @@ public class JsonSerializer implements ODataSerializer {
     }
   }
 
-  protected void clientLinks(final Linked linked, final JsonGenerator jgen) throws IOException {
+  protected void clientLinks(final Linked linked, final JsonGenerator jgen)
+      throws IOException, EdmPrimitiveTypeException {
     final Map<String, List<String>> entitySetLinks = new HashMap<String, List<String>>();
     for (Link link : linked.getNavigationLinks()) {
       for (Annotation annotation : link.getAnnotations()) {
@@ -179,14 +185,15 @@ public class JsonSerializer implements ODataSerializer {
     }
   }
 
-  protected void serverLinks(final Linked linked, final JsonGenerator jgen) throws IOException {
+  protected void serverLinks(final Linked linked, final JsonGenerator jgen)
+      throws IOException, EdmPrimitiveTypeException {
     if (linked instanceof Entity) {
       for (Link link : ((Entity) linked).getMediaEditLinks()) {
         if (StringUtils.isNotBlank(link.getHref())) {
           jgen.writeStringField(
-                  link.getTitle() + StringUtils.prependIfMissing(
-                          version.getJSONMap().get(ODataServiceVersion.JSON_MEDIAEDIT_LINK), "@"),
-                  link.getHref());
+              link.getTitle() + StringUtils.prependIfMissing(
+                  version.getJSONMap().get(ODataServiceVersion.JSON_MEDIAEDIT_LINK), "@"),
+              link.getHref());
         }
       }
     }
@@ -194,8 +201,8 @@ public class JsonSerializer implements ODataSerializer {
     for (Link link : linked.getAssociationLinks()) {
       if (StringUtils.isNotBlank(link.getHref())) {
         jgen.writeStringField(
-                link.getTitle() + version.getJSONMap().get(ODataServiceVersion.JSON_ASSOCIATION_LINK),
-                link.getHref());
+            link.getTitle() + version.getJSONMap().get(ODataServiceVersion.JSON_ASSOCIATION_LINK),
+            link.getHref());
       }
     }
 
@@ -206,8 +213,8 @@ public class JsonSerializer implements ODataSerializer {
 
       if (StringUtils.isNotBlank(link.getHref())) {
         jgen.writeStringField(
-                link.getTitle() + version.getJSONMap().get(ODataServiceVersion.JSON_NAVIGATION_LINK),
-                link.getHref());
+            link.getTitle() + version.getJSONMap().get(ODataServiceVersion.JSON_NAVIGATION_LINK),
+            link.getHref());
       }
 
       if (link.getInlineEntity() != null) {
@@ -224,80 +231,113 @@ public class JsonSerializer implements ODataSerializer {
     }
   }
 
-  private void collection(final JsonGenerator jgen, final String itemType, final CollectionValue value)
-          throws IOException {
-
+  private void collection(final JsonGenerator jgen, final EdmTypeInfo typeInfo,
+      final ValueType valueType, final List<?> value) throws IOException, EdmPrimitiveTypeException {
     jgen.writeStartArray();
-    for (Value item : value.get()) {
-      value(jgen, itemType, item);
+    for (Object item : value) {
+      final EdmTypeInfo itemTypeInfo = typeInfo == null ? null :
+          new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
+      switch (valueType) {
+      case COLLECTION_PRIMITIVE:
+        primitiveValue(jgen, itemTypeInfo, item);
+        break;
+      case COLLECTION_GEOSPATIAL:
+        jgen.writeStartObject();
+        geoSerializer.serialize(jgen, (Geospatial) item);
+        jgen.writeEndObject();
+        break;
+      case COLLECTION_ENUM:
+        jgen.writeString(item.toString());
+        break;
+      case COLLECTION_COMPLEX:
+        @SuppressWarnings("unchecked")
+        final List<Property> complexItem = (List<Property>) item;
+        complexValue(jgen, itemTypeInfo, complexItem, null);
+        break;
+      case COLLECTION_LINKED_COMPLEX:
+        final LinkedComplexValue complexItem2 = (LinkedComplexValue) item;
+        complexValue(jgen, itemTypeInfo, complexItem2.getValue(), complexItem2);
+      default:
+        break;
+      }
     }
     jgen.writeEndArray();
   }
 
-  protected void primitiveValue(final JsonGenerator jgen, final EdmTypeInfo typeInfo, final PrimitiveValue value)
-          throws IOException {
+  protected void primitiveValue(final JsonGenerator jgen, final EdmTypeInfo typeInfo, final Object value)
+      throws IOException, EdmPrimitiveTypeException {
+    final EdmPrimitiveTypeKind kind = typeInfo == null ? null : typeInfo.getPrimitiveTypeKind();
+    final boolean isNumber = kind == null ? value instanceof Number : ArrayUtils.contains(NUMBER_TYPES, kind);
+    final boolean isBoolean = kind == null ? value instanceof Boolean : kind == EdmPrimitiveTypeKind.Boolean;
 
-    final boolean isNumber = typeInfo == null
-            ? NumberUtils.isNumber(value.get())
-            : ArrayUtils.contains(NUMBER_TYPES, typeInfo.getPrimitiveTypeKind());
-    final boolean isBoolean = typeInfo == null
-            ? (value.get().equalsIgnoreCase(Boolean.TRUE.toString())
-            || value.get().equalsIgnoreCase(Boolean.FALSE.toString()))
-            : typeInfo.getPrimitiveTypeKind() == EdmPrimitiveTypeKind.Boolean;
-
-    if (isNumber) {
-      jgen.writeNumber(value.get());
+    if (value == null) {
+      jgen.writeNull();
     } else if (isBoolean) {
-      jgen.writeBoolean(BooleanUtils.toBoolean(value.get()));
+      jgen.writeBoolean((Boolean) value);
     } else {
-      jgen.writeString(value.get());
+      final String serialized = kind == null ? value.toString() :
+          EdmPrimitiveTypeFactory.getInstance(kind)  // TODO: add facets
+              .valueToString(value, null, null, Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null);
+      if (isNumber) {
+        jgen.writeNumber(serialized);
+      } else {
+        jgen.writeString(serialized);
+      }
+    }
+  }
+
+  private void complexValue(final JsonGenerator jgen, final EdmTypeInfo typeInfo,
+      final List<Property> value, final Linked linked)
+      throws IOException, EdmPrimitiveTypeException {
+    jgen.writeStartObject();
+
+    if (typeInfo != null) {
+      jgen.writeStringField(version.getJSONMap().get(ODataServiceVersion.JSON_TYPE), typeInfo.external(version));
     }
+
+    for (Property property : value) {
+      valuable(jgen, property, property.getName());
+    }
+    if (linked != null) {
+      links(linked, jgen);
+    }
+
+    jgen.writeEndObject();
   }
 
-  private void value(final JsonGenerator jgen, final String type, final Value value) throws IOException {
-    final EdmTypeInfo typeInfo = type == null
-            ? null
-            : new EdmTypeInfo.Builder().setTypeExpression(type).build();
+  private void value(final JsonGenerator jgen, final String type, final Valuable value)
+      throws IOException, EdmPrimitiveTypeException {
+    final EdmTypeInfo typeInfo = type == null ? null : new EdmTypeInfo.Builder().setTypeExpression(type).build();
 
-    if (value == null || value.isNull()) {
+    if (value.isNull()) {
       jgen.writeNull();
     } else if (value.isPrimitive()) {
       primitiveValue(jgen, typeInfo, value.asPrimitive());
     } else if (value.isEnum()) {
-      jgen.writeString(value.asEnum().get());
+      jgen.writeString(value.asEnum().toString());
     } else if (value.isGeospatial()) {
       jgen.writeStartObject();
-      geoSerializer.serialize(jgen, value.asGeospatial().get());
+      geoSerializer.serialize(jgen, value.asGeospatial());
       jgen.writeEndObject();
     } else if (value.isCollection()) {
-      collection(jgen, typeInfo == null ? null : typeInfo.getFullQualifiedName().toString(), value.asCollection());
+      collection(jgen, typeInfo, value.getValueType(), value.asCollection());
+    } else if (value.isLinkedComplex()) {
+      complexValue(jgen, typeInfo, value.asLinkedComplex().getValue(), value.asLinkedComplex());
     } else if (value.isComplex()) {
-      jgen.writeStartObject();
-
-      if (typeInfo != null) {
-        jgen.writeStringField(version.getJSONMap().get(ODataServiceVersion.JSON_TYPE), typeInfo.external(version));
-      }
-
-      for (Property property : value.asComplex().get()) {
-        valuable(jgen, property, property.getName());
-      }
-      if (value.isLinkedComplex()) {
-        links(value.asLinkedComplex(), jgen);
-      }
-
-      jgen.writeEndObject();
+      complexValue(jgen, typeInfo, value.asComplex(), null);
     }
   }
 
-  protected void valuable(final JsonGenerator jgen, final Valuable valuable, final String name) throws IOException {
-    if (!Constants.VALUE.equals(name) && !(valuable instanceof Annotation) && !valuable.getValue().isComplex()) {
+  protected void valuable(final JsonGenerator jgen, final Valuable valuable, final String name)
+      throws IOException, EdmPrimitiveTypeException {
+    if (!Constants.VALUE.equals(name) && !(valuable instanceof Annotation) && !valuable.isComplex()) {
       String type = valuable.getType();
-      if (StringUtils.isBlank(type) && valuable.getValue().isPrimitive() || valuable.getValue().isNull()) {
+      if (StringUtils.isBlank(type) && valuable.isPrimitive() || valuable.isNull()) {
         type = EdmPrimitiveTypeKind.String.getFullQualifiedName().toString();
       }
       if (StringUtils.isNotBlank(type)) {
         jgen.writeFieldName(
-                name + StringUtils.prependIfMissing(version.getJSONMap().get(ODataServiceVersion.JSON_TYPE), "@"));
+            name + StringUtils.prependIfMissing(version.getJSONMap().get(ODataServiceVersion.JSON_TYPE), "@"));
         jgen.writeString(new EdmTypeInfo.Builder().setTypeExpression(type).build().external(version));
       }
     }
@@ -309,6 +349,6 @@ public class JsonSerializer implements ODataSerializer {
     }
 
     jgen.writeFieldName(name);
-    value(jgen, valuable.getType(), valuable.getValue());
+    value(jgen, valuable.getType(), valuable);
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a2874142/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/CommonPrimitiveTypeTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/CommonPrimitiveTypeTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/CommonPrimitiveTypeTest.java
index 2673427..a9e4794 100644
--- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/CommonPrimitiveTypeTest.java
+++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/CommonPrimitiveTypeTest.java
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.math.BigDecimal;
+import java.sql.Timestamp;
 import java.util.Calendar;
 import java.util.UUID;
 
@@ -123,7 +124,7 @@ public class CommonPrimitiveTypeTest extends PrimitiveTypeBaseTest {
             EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean).getDefaultType());
     assertEquals(Short.class, EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Byte).getDefaultType());
     assertEquals(Calendar.class, EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Date).getDefaultType());
-    assertEquals(Calendar.class,
+    assertEquals(Timestamp.class,
             EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.DateTimeOffset).getDefaultType());
     assertEquals(BigDecimal.class,
             EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Decimal).getDefaultType());

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a2874142/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataJsonSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataJsonSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataJsonSerializer.java
index 62634da..bdd6b54 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataJsonSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataJsonSerializer.java
@@ -33,6 +33,7 @@ import org.apache.olingo.commons.api.edm.Edm;
 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.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.edm.EdmProperty;
 import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
@@ -105,12 +106,14 @@ public class ODataJsonSerializer implements ODataSerializer {
       json.close();
     } catch (final IOException e) {
       throw new ODataRuntimeException(e);
+    } catch (final EdmPrimitiveTypeException e) {
+      throw new ODataRuntimeException(e);
     }
     return buffer.getInputStream();
   }
 
   protected void writeEntity(final EdmEntityType entityType, final Entity entity, final ContextURL contextURL,
-      JsonGenerator json) throws IOException {
+      JsonGenerator json) throws IOException, EdmPrimitiveTypeException {
     json.writeStartObject();
     if (contextURL != null) {
       json.writeStringField(Constants.JSON_CONTEXT, contextURL.getURI().toASCIIString());
@@ -137,7 +140,10 @@ public class ODataJsonSerializer implements ODataSerializer {
       } else {
         if (edmProperty.isPrimitive()) {
           final EdmPrimitiveType type = (EdmPrimitiveType) edmProperty.getType();
-          final String value = property.getValue().asPrimitive().get();
+          final String value = type.valueToString(property.asPrimitive(),
+              edmProperty.isNullable(), edmProperty.getMaxLength(),
+              edmProperty.getPrecision(), edmProperty.getScale(),
+              edmProperty.isUnicode());
           if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean)) {
             json.writeBoolean(Boolean.parseBoolean(value));
           } else if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Byte)
@@ -185,6 +191,8 @@ public class ODataJsonSerializer implements ODataSerializer {
       json.close();
     } catch (final IOException e) {
       throw new ODataRuntimeException(e);
+    } catch (final EdmPrimitiveTypeException e) {
+      throw new ODataRuntimeException(e);
     }
     return buffer.getInputStream();
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a2874142/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/SampleJsonProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/SampleJsonProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/SampleJsonProcessor.java
index 5c6c636..ebe30e1 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/SampleJsonProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/SampleJsonProcessor.java
@@ -25,13 +25,13 @@ 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.Property;
+import org.apache.olingo.commons.api.data.ValueType;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.commons.api.format.ODataFormat;
 import org.apache.olingo.commons.core.data.EntityImpl;
 import org.apache.olingo.commons.core.data.EntitySetImpl;
-import org.apache.olingo.commons.core.data.PrimitiveValueImpl;
 import org.apache.olingo.commons.core.data.PropertyImpl;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.ODataRequest;
@@ -99,17 +99,17 @@ public class SampleJsonProcessor implements EntitySetProcessor, EntityProcessor
       Property property = new PropertyImpl();
       property.setName("PropertyString");
       property.setType("String"); //"dummyType");
-      property.setValue(new PrimitiveValueImpl("dummyValue"));
+      property.setValue(ValueType.PRIMITIVE, "dummyValue");
       entity.getProperties().add(property);
       Property propertyInt = new PropertyImpl();
       propertyInt.setName("PropertyInt16");
       // propertyInt.setType("Edm.Int32");
-      propertyInt.setValue(new PrimitiveValueImpl("42"));
+      propertyInt.setValue(ValueType.PRIMITIVE, 42);
       entity.getProperties().add(propertyInt);
       Property propertyGuid = new PropertyImpl();
       propertyGuid.setName("PropertyGuid");
       propertyGuid.setType("Edm.Guid");
-      propertyGuid.setValue(new PrimitiveValueImpl(UUID.randomUUID().toString()));
+      propertyGuid.setValue(ValueType.PRIMITIVE, UUID.randomUUID());
       entity.getProperties().add(propertyGuid);
       return entity;
     }