You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by fm...@apache.org on 2014/05/13 18:59:33 UTC

git commit: [OLINGO-260] provided primitive keys integration test on proxy + some refactoring ... still missing EdmTime review: what about BigDecimal in place of Duration?

Repository: olingo-odata4
Updated Branches:
  refs/heads/master 3daee521b -> 32518c1b0


[OLINGO-260] provided primitive keys integration test on proxy + some refactoring ... still missing EdmTime review: what about BigDecimal in place of Duration?


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

Branch: refs/heads/master
Commit: 32518c1b0bcca1b00f103ccfacb59696b4ed5509
Parents: 3daee52
Author: fmartelli <fa...@gmail.com>
Authored: Tue May 13 18:59:14 2014 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Tue May 13 18:59:14 2014 +0200

----------------------------------------------------------------------
 .../commons/AbstractInvocationHandler.java      |  13 +-
 .../commons/ComplexTypeInvocationHandler.java   |  47 +-----
 .../commons/EntityTypeInvocationHandler.java    |  44 +-----
 .../olingo/ext/proxy/utils/CoreUtils.java       | 110 +++++---------
 fit/src/it/primitiveKeysServiceV3/pom.xml       |  93 ++++++++++++
 fit/src/it/primitiveKeysServiceV3/verify.groovy |  20 +++
 .../org/apache/olingo/fit/AbstractServices.java |  85 ++++++++---
 .../org/apache/olingo/fit/V3PrimitiveKeys.java  |  55 +++++++
 .../main/resources/V30/Driver/'2'/entity.xml    |  38 +++++
 .../resources/V30/primitiveKeysMetadata.xml     | 147 +++++++++++++++++++
 .../main/webapp/WEB-INF/applicationContext.xml  |   1 +
 .../olingo/fit/proxy/v3/AbstractTestITCase.java |   3 +
 .../olingo/fit/proxy/v3/PropertyTestITCase.java |  56 +++++++
 .../olingo/fit/proxy/v4/PropertyTestITCase.java |  56 +++++++
 .../client/core/v3/PrimitiveValueTest.java      |   2 +-
 .../core/edm/primitivetype/EdmDuration.java     |   3 +-
 .../commons/core/edm/primitivetype/EdmTime.java |  48 +-----
 17 files changed, 579 insertions(+), 242 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java
index 3ffb6be..9da6aab 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java
@@ -193,14 +193,7 @@ abstract class AbstractInvocationHandler<C extends CommonEdmEnabledODataClient<?
 
     final EdmTypeInfo edmType = new EdmTypeInfo.Builder().
             setEdm(client.getCachedEdm()).setTypeExpression(annotation.returnType()).build();
-
-    if (edmType.isEnumType()) {
-      throw new UnsupportedOperationException("Usupported enum type " + edmType.getFullQualifiedName());
-    }
-
-    if (edmType.isPrimitiveType() || edmType.isComplexType()) {
-      return CoreUtils.getValueFromProperty(client, (CommonODataProperty) result, method.getGenericReturnType());
-    }
+    
     if (edmType.isEntityType()) {
       if (edmType.isCollection()) {
         final ParameterizedType collType = (ParameterizedType) method.getReturnType().getGenericInterfaces()[0];
@@ -220,9 +213,9 @@ abstract class AbstractInvocationHandler<C extends CommonEdmEnabledODataClient<?
                 method.getReturnType(),
                 false);
       }
+    }else{
+      return CoreUtils.getValueFromProperty(client, (CommonODataProperty) result, method.getGenericReturnType(), null);
     }
-
-    throw new IllegalArgumentException("Could not process the functionImport information");
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java
index 28bf280..fe645ae 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java
@@ -20,7 +20,6 @@ package org.apache.olingo.ext.proxy.commons;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Proxy;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
@@ -32,7 +31,6 @@ import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
 import org.apache.olingo.commons.api.domain.CommonODataProperty;
 import org.apache.olingo.commons.api.domain.ODataComplexValue;
 import org.apache.olingo.commons.api.domain.ODataLinked;
-import org.apache.olingo.commons.api.domain.ODataValue;
 import org.apache.olingo.commons.api.edm.EdmElement;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
@@ -77,7 +75,7 @@ public class ComplexTypeInvocationHandler<C extends CommonEdmEnabledODataClient<
   }
 
   @SuppressWarnings({"unchecked", "rawtypes"})
-  static ComplexTypeInvocationHandler<?> getInstance(
+  public static ComplexTypeInvocationHandler<?> getInstance(
           final CommonEdmEnabledODataClient<?> client,
           final ODataComplexValue<?> complex,
           final Class<?> typeRef,
@@ -112,48 +110,7 @@ public class ComplexTypeInvocationHandler<C extends CommonEdmEnabledODataClient<
   @Override
   protected Object getPropertyValue(final String name, final Type type) {
     try {
-      final Object res;
-
-      final CommonODataProperty property = getComplex().get(name);
-      if (property == null) {
-        res = null;
-      } else if (property.hasComplexValue()) {
-        res = Proxy.newProxyInstance(
-                Thread.currentThread().getContextClassLoader(),
-                new Class<?>[] {(Class<?>) type},
-                ComplexTypeInvocationHandler.getInstance(
-                client, property.getValue().asComplex(), (Class<?>) type, targetHandler));
-
-      } else if (property.hasCollectionValue()) {
-        final ParameterizedType collType = (ParameterizedType) type;
-        final Class<?> collItemClass = (Class<?>) collType.getActualTypeArguments()[0];
-
-        final ArrayList<Object> collection = new ArrayList<Object>();
-
-        final Iterator<ODataValue> collPropItor = property.getValue().asCollection().iterator();
-        while (collPropItor.hasNext()) {
-          final ODataValue value = collPropItor.next();
-          if (value.isPrimitive()) {
-            collection.add(CoreUtils.primitiveValueToObject(value.asPrimitive()));
-          } else if (value.isComplex()) {
-            final Object collItem = Proxy.newProxyInstance(
-                    Thread.currentThread().getContextClassLoader(),
-                    new Class<?>[] {collItemClass},
-                    ComplexTypeInvocationHandler.getInstance(
-                    client, value.asComplex(), collItemClass, targetHandler));
-
-            collection.add(collItem);
-          }
-        }
-
-        res = collection;
-      } else {
-        res = type == null
-                ? CoreUtils.getValueFromProperty(client, property)
-                : CoreUtils.getValueFromProperty(client, property, type);
-      }
-
-      return res;
+      return CoreUtils.getValueFromProperty(client, getComplex().get(name), type, targetHandler);
     } catch (Exception e) {
       throw new IllegalArgumentException("Error getting value for property '" + name + "'", e);
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
index 0e093b4..9f81634 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
@@ -21,15 +21,11 @@ package org.apache.olingo.ext.proxy.commons;
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Proxy;
 import java.lang.reflect.Type;
 import java.net.URI;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 import org.apache.commons.io.IOUtils;
@@ -40,7 +36,6 @@ import org.apache.olingo.client.core.uri.URIUtils;
 import org.apache.olingo.commons.api.domain.CommonODataEntity;
 import org.apache.olingo.commons.api.domain.CommonODataProperty;
 import org.apache.olingo.commons.api.domain.ODataLinked;
-import org.apache.olingo.commons.api.domain.ODataValue;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.format.ODataMediaFormat;
@@ -194,45 +189,8 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
       Object res;
       if (propertyChanges.containsKey(name)) {
         res = propertyChanges.get(name);
-      } else if (property == null) {
-        res = null;
-      } else if (property.hasComplexValue()) {
-        res = Proxy.newProxyInstance(
-                Thread.currentThread().getContextClassLoader(),
-                new Class<?>[] {(Class<?>) type},
-                ComplexTypeInvocationHandler.getInstance(
-                        client, property.getValue().asComplex(), (Class<?>) type, this));
-
-        addPropertyChanges(name, res);
-      } else if (property.hasCollectionValue()) {
-        final ParameterizedType collType = (ParameterizedType) type;
-        final Class<?> collItemClass = (Class<?>) collType.getActualTypeArguments()[0];
-
-        final ArrayList<Object> collection = new ArrayList<Object>();
-
-        final Iterator<ODataValue> collPropItor = property.getValue().asCollection().iterator();
-        while (collPropItor.hasNext()) {
-          final ODataValue value = collPropItor.next();
-          if (value.isPrimitive()) {
-            collection.add(CoreUtils.primitiveValueToObject(value.asPrimitive()));
-          } else if (value.isComplex()) {
-            final Object collItem = Proxy.newProxyInstance(
-                    Thread.currentThread().getContextClassLoader(),
-                    new Class<?>[] {collItemClass},
-                    ComplexTypeInvocationHandler.getInstance(
-                            client, value.asComplex(), collItemClass, this));
-
-            collection.add(collItem);
-          }
-        }
-
-        res = collection;
-
-        addPropertyChanges(name, res);
       } else {
-        res = type == null
-                ? CoreUtils.getValueFromProperty(client, property)
-                : CoreUtils.getValueFromProperty(client, property, type);
+        res = CoreUtils.getValueFromProperty(client, property, type, this);
 
         if (res != null) {
           addPropertyChanges(name, res);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
index ea2832b..981d285 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
@@ -33,10 +33,8 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.ServiceLoader;
 import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
 import org.apache.olingo.client.api.v3.UnsupportedInV3Exception;
-import org.apache.olingo.client.core.edm.xml.AbstractComplexType;
 import org.apache.olingo.commons.api.domain.CommonODataEntity;
 import org.apache.olingo.commons.api.domain.CommonODataProperty;
 import org.apache.olingo.commons.api.domain.ODataLink;
@@ -48,12 +46,12 @@ import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
-import org.apache.olingo.ext.proxy.api.annotations.ComplexType;
 import org.apache.olingo.ext.proxy.api.annotations.CompoundKeyElement;
 import org.apache.olingo.ext.proxy.api.annotations.Key;
 import org.apache.olingo.ext.proxy.api.annotations.Property;
 import org.apache.olingo.ext.proxy.commons.AbstractTypeInvocationHandler;
 import org.apache.olingo.ext.proxy.commons.ComplexTypeInvocationHandler;
+import org.apache.olingo.ext.proxy.commons.EntityTypeInvocationHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -375,97 +373,59 @@ public final class CoreUtils {
 
   @SuppressWarnings("unchecked")
   public static Object getValueFromProperty(
-          final CommonEdmEnabledODataClient<?> client, final CommonODataProperty property)
+          final CommonEdmEnabledODataClient<?> client,
+          final CommonODataProperty property,
+          final Type typeRef,
+          final EntityTypeInvocationHandler<?> entityHandler)
           throws InstantiationException, IllegalAccessException {
 
-    final Object value;
+    final Object res;
 
-    if (property == null || property.hasNullValue()) {
-      value = null;
-    } else if (property.hasCollectionValue()) {
-      value = new ArrayList<Object>();
-
-      final Iterator<ODataValue> collPropItor = property.getValue().asCollection().iterator();
-      while (collPropItor.hasNext()) {
-        final ODataValue odataValue = collPropItor.next();
-        if (odataValue.isPrimitive()) {
-          ((Collection) value).add(primitiveValueToObject(odataValue.asPrimitive()));
-        }
-        if (odataValue.isComplex()) {
-          final Object collItem =
-                  buildComplexInstance(client, property.getName(), odataValue.asComplex().iterator());
-          ((Collection) value).add(collItem);
-        }
-      }
-    } else if (property.hasPrimitiveValue()) {
-      value = primitiveValueToObject(property.getPrimitiveValue());
-    } else if (property.hasComplexValue()) {
-      value = buildComplexInstance(client, property.getValue().asComplex().getTypeName(),
-              property.getValue().asComplex().iterator());
+    Class<?> internalRef;
+    if (typeRef == null) {
+      internalRef = null;
     } else {
-      throw new IllegalArgumentException("Invalid property " + property);
-    }
-
-    return value;
-  }
-
-  @SuppressWarnings("unchecked")
-  private static <C extends AbstractComplexType> C buildComplexInstance(
-          final CommonEdmEnabledODataClient<?> client,
-          final String name,
-          final Iterator<CommonODataProperty> properties) {
-
-    for (C complex : (Iterable<C>) ServiceLoader.load(AbstractComplexType.class)) {
-      final ComplexType ann = complex.getClass().getAnnotation(ComplexType.class);
-      final String fn = ann == null ? null : ClassUtils.getNamespace(complex.getClass()) + "." + ann.name();
-
-      if (name.equals(fn)) {
-        populate(client, complex, Property.class, properties);
-        return complex;
+      try {
+        internalRef = (Class<?>) ((ParameterizedType) typeRef).getActualTypeArguments()[0];
+      } catch (ClassCastException e) {
+        internalRef = (Class<?>) typeRef;
       }
     }
 
-    return null;
-  }
-
-  @SuppressWarnings({"unchecked", "rawtypes"})
-  public static Object getValueFromProperty(
-          final CommonEdmEnabledODataClient<?> client,
-          final CommonODataProperty property, final Type type)
-          throws InstantiationException, IllegalAccessException {
-
-    final Object value;
-
     if (property == null || property.hasNullValue()) {
-      value = null;
-    } else if (property.hasCollectionValue()) {
-      value = new ArrayList();
+      res = null;
+    } else if (property.hasComplexValue()) {
+      res = Proxy.newProxyInstance(
+              Thread.currentThread().getContextClassLoader(),
+              new Class<?>[] {internalRef},
+              ComplexTypeInvocationHandler.getInstance(
+              client, property.getValue().asComplex(), internalRef, entityHandler));
 
-      final ParameterizedType collType = (ParameterizedType) type;
-      final Class<?> collItemClass = (Class<?>) collType.getActualTypeArguments()[0];
+    } else if (property.hasCollectionValue()) {
+      final ArrayList<Object> collection = new ArrayList<Object>();
 
       final Iterator<ODataValue> collPropItor = property.getValue().asCollection().iterator();
       while (collPropItor.hasNext()) {
-        final ODataValue odataValue = collPropItor.next();
-        if (odataValue.isPrimitive()) {
-          ((Collection) value).add(primitiveValueToObject(odataValue.asPrimitive()));
-        }
-        if (odataValue.isComplex()) {
+        final ODataValue value = collPropItor.next();
+        if (value.isPrimitive()) {
+          collection.add(CoreUtils.primitiveValueToObject(value.asPrimitive()));
+        } else if (value.isComplex()) {
           final Object collItem = Proxy.newProxyInstance(
                   Thread.currentThread().getContextClassLoader(),
-                  new Class<?>[] {collItemClass},
-                  new ComplexTypeInvocationHandler(client, odataValue.asComplex(), collItemClass, null));
-          populate(client, collItem, Property.class, odataValue.asComplex().iterator());
-          ((Collection) value).add(collItem);
+                  new Class<?>[] {internalRef},
+                  ComplexTypeInvocationHandler.getInstance(
+                  client, value.asComplex(), internalRef, entityHandler));
+
+          collection.add(collItem);
         }
       }
-    } else if (property.hasPrimitiveValue()) {
-      value = primitiveValueToObject(property.getPrimitiveValue());
+
+      res = collection;
     } else {
-      throw new IllegalArgumentException("Invalid property " + property);
+      res = CoreUtils.primitiveValueToObject(property.getPrimitiveValue());
     }
 
-    return value;
+    return res;
   }
 
   private static String firstValidEntityKey(final Class<?> entityTypeRef) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/fit/src/it/primitiveKeysServiceV3/pom.xml
----------------------------------------------------------------------
diff --git a/fit/src/it/primitiveKeysServiceV3/pom.xml b/fit/src/it/primitiveKeysServiceV3/pom.xml
new file mode 100644
index 0000000..a01701f
--- /dev/null
+++ b/fit/src/it/primitiveKeysServiceV3/pom.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>pojogen-maven-plugin-v3test</artifactId>
+  <groupId>org.apache.olingo</groupId>
+  <version>@project.version@</version>
+  <name>${project.artifactId}</name>
+  <description>A simple IT verifying the basic use case of pojogen-man-plugin.</description>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+  
+  <dependencies>
+    <dependency>
+      <artifactId>pojogen-maven-plugin</artifactId>
+      <groupId>org.apache.olingo</groupId>
+      <version>@project.version@</version>
+      <scope>runtime</scope>
+    </dependency>
+    
+    <dependency>
+      <artifactId>olingo-client-proxy</artifactId>
+      <groupId>org.apache.olingo</groupId>
+      <version>@project.version@</version>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <version>1.8</version>
+        <executions>
+          <execution>
+            <phase>process-sources</phase>
+            <goals>
+              <goal>add-source</goal>
+            </goals>
+            <configuration>
+              <sources>
+                <source>${project.build.directory}/generated-sources</source>
+              </sources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      
+      <plugin>
+        <groupId>@project.groupId@</groupId>
+        <artifactId>pojogen-maven-plugin</artifactId>
+        <version>@project.version@</version>
+        <executions>
+          <execution>
+            <configuration>
+              <outputDirectory>${project.build.directory}/generated-sources</outputDirectory>
+              <serviceRootURL>http://localhost:9080/stub/StaticService/V30/PrimitiveKeys.svc</serviceRootURL>
+              <basePackage>org.apache.olingo.fit.proxy.v3.primitivekeys</basePackage>
+            </configuration>
+            <id>v3pojoGen</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>v3pojoGen</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/fit/src/it/primitiveKeysServiceV3/verify.groovy
----------------------------------------------------------------------
diff --git a/fit/src/it/primitiveKeysServiceV3/verify.groovy b/fit/src/it/primitiveKeysServiceV3/verify.groovy
new file mode 100644
index 0000000..9b74ad2
--- /dev/null
+++ b/fit/src/it/primitiveKeysServiceV3/verify.groovy
@@ -0,0 +1,20 @@
+/**
+ * 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.
+ */
+File basepkg = new File( basedir, "target/generated-sources/ojc-plugin/org/apache/olingo/fit/proxy/v3" );
+assert basepkg.isDirectory() && basepkg.listFiles().length>0;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
index da7907c..0bb7c7d 100644
--- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
+++ b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
@@ -83,6 +83,7 @@ import org.apache.olingo.commons.core.data.AtomEntityImpl;
 import org.apache.olingo.commons.core.data.AtomPropertyImpl;
 import org.apache.olingo.commons.core.data.AtomSerializer;
 import org.apache.olingo.commons.core.data.JSONEntityImpl;
+import org.apache.olingo.commons.core.data.JSONPropertyImpl;
 import org.apache.olingo.commons.core.data.NullValueImpl;
 import org.apache.olingo.commons.core.data.PrimitiveValueImpl;
 import org.apache.olingo.fit.metadata.EntityType;
@@ -209,6 +210,50 @@ public abstract class AbstractServices {
     }
   }
 
+  // ----------------------------------------------
+  // just for non nullable property test into PropertyTestITCase
+  // ----------------------------------------------
+  @PATCH
+  @Path("/Driver('2')")
+  public Response patchDriver() {
+    return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(version), new Exception("Non nullable properties"));
+  }
+
+  @GET
+  @Path("/StoredPIs(1000)")
+  public Response getStoredPI(@Context UriInfo uriInfo) {
+    final JSONEntityImpl entity = new JSONEntityImpl();
+    entity.setType("Microsoft.Test.OData.Services.ODataWCFService.StoredPI");
+    final Property id = new JSONPropertyImpl();
+    id.setType("Edm.Int32");
+    id.setName("StoredPIID");
+    id.setValue(new PrimitiveValueImpl("1000"));
+    entity.getProperties().add(id);
+    final Link edit = new LinkImpl();
+    edit.setHref(uriInfo.getRequestUri().toASCIIString());
+    edit.setRel("edit");
+    edit.setTitle("StoredPI");
+    entity.setEditLink(edit);
+
+    final ByteArrayOutputStream content = new ByteArrayOutputStream();
+    final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
+    try {
+      mapper.writeValue(writer, new JSONEntryContainer(null, null, entity));
+      return xml.createResponse(new ByteArrayInputStream(content.toByteArray()), null, Accept.JSON_FULLMETA);
+    } catch (Exception e) {
+      LOG.error("While creating StoredPI", e);
+      return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(version),e);
+    }
+  }
+
+  @PATCH
+  @Path("/StoredPIs(1000)")
+  public Response patchStoredPI() {
+    // just for non nullable property test into PropertyTestITCase
+    return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(version), new Exception("Non nullable properties"));
+  }
+  // ----------------------------------------------
+
   protected Response bodyPartRequest(final MimeBodyPart body) throws Exception {
     return bodyPartRequest(body, Collections.<String, String>emptyMap());
   }
@@ -420,7 +465,7 @@ public abstract class AbstractServices {
       } else {
         final ResWrap<JSONEntityImpl> jcont = mapper.readValue(IOUtils.toInputStream(changes, Constants.ENCODING),
                 new TypeReference<JSONEntityImpl>() {
-                });
+        });
 
         entryChanges = dataBinder.toAtomEntity(jcont.getPayload());
       }
@@ -607,8 +652,8 @@ public abstract class AbstractServices {
         } else {
           final ResWrap<JSONEntityImpl> jcontainer =
                   mapper.readValue(IOUtils.toInputStream(entity, Constants.ENCODING),
-                          new TypeReference<JSONEntityImpl>() {
-                          });
+                  new TypeReference<JSONEntityImpl>() {
+          });
 
           entry = dataBinder.toAtomEntity(jcontainer.getPayload());
 
@@ -635,7 +680,7 @@ public abstract class AbstractServices {
       ResWrap<AtomEntityImpl> result = atomDeserializer.read(serialization, AtomEntityImpl.class);
       result = new ResWrap<AtomEntityImpl>(
               URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX)
-                      + entitySetName + Constants.get(version, ConstantKey.ODATA_METADATA_ENTITY_SUFFIX)),
+              + entitySetName + Constants.get(version, ConstantKey.ODATA_METADATA_ENTITY_SUFFIX)),
               null, result.getPayload());
 
       final String path = Commons.getEntityBasePath(entitySetName, entityKey);
@@ -697,7 +742,7 @@ public abstract class AbstractServices {
       final FSManager fsManager = FSManager.instance(version);
       fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
               fsManager.getAbsolutePath(Commons.getEntityBasePath("Person", entityId) + Constants.get(version,
-                              ConstantKey.ENTITY), Accept.ATOM));
+              ConstantKey.ENTITY), Accept.ATOM));
 
       return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
     } catch (Exception e) {
@@ -749,9 +794,9 @@ public abstract class AbstractServices {
         final Long newSalary = Long.valueOf(salaryMatcher.group(1)) + n;
         newContent = newContent.
                 replaceAll("\"Salary\":" + salaryMatcher.group(1) + ",",
-                        "\"Salary\":" + newSalary + ",").
+                "\"Salary\":" + newSalary + ",").
                 replaceAll("\\<d:Salary m:type=\"Edm.Int32\"\\>" + salaryMatcher.group(1) + "</d:Salary\\>",
-                        "<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
+                "<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
       }
 
       FSManager.instance(version).putInMemory(IOUtils.toInputStream(newContent, Constants.ENCODING),
@@ -790,7 +835,7 @@ public abstract class AbstractServices {
       final FSManager fsManager = FSManager.instance(version);
       fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
               fsManager.getAbsolutePath(Commons.getEntityBasePath("Product", entityId) + Constants.get(version,
-                              ConstantKey.ENTITY), Accept.ATOM));
+              ConstantKey.ENTITY), Accept.ATOM));
 
       return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
     } catch (Exception e) {
@@ -826,7 +871,7 @@ public abstract class AbstractServices {
       final FSManager fsManager = FSManager.instance(version);
       fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
               fsManager.getAbsolutePath(Commons.getEntityBasePath("ComputerDetail", entityId) + Constants.get(version,
-                              ConstantKey.ENTITY), Accept.ATOM));
+              ConstantKey.ENTITY), Accept.ATOM));
 
       return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
     } catch (Exception e) {
@@ -971,7 +1016,7 @@ public abstract class AbstractServices {
         } else {
           mapper.writeValue(
                   writer, new JSONFeedContainer(container.getContextURL(), container.getMetadataETag(),
-                          dataBinder.toJSONEntitySet(container.getPayload())));
+                  dataBinder.toJSONEntitySet(container.getPayload())));
         }
 
         return xml.createResponse(
@@ -1696,8 +1741,8 @@ public abstract class AbstractServices {
               mapper.writeValue(
                       writer,
                       new JSONFeedContainer(container.getContextURL(),
-                              container.getMetadataETag(),
-                              dataBinder.toJSONEntitySet((AtomEntitySetImpl) container.getPayload())));
+                      container.getMetadataETag(),
+                      dataBinder.toJSONEntitySet((AtomEntitySetImpl) container.getPayload())));
             }
           } else {
             final ResWrap<Entity> container =
@@ -1710,8 +1755,8 @@ public abstract class AbstractServices {
               mapper.writeValue(
                       writer,
                       new JSONEntryContainer(container.getContextURL(),
-                              container.getMetadataETag(),
-                              dataBinder.toJSONEntity((AtomEntityImpl) container.getPayload())));
+                      container.getMetadataETag(),
+                      dataBinder.toJSONEntity((AtomEntityImpl) container.getPayload())));
             }
           }
 
@@ -1781,9 +1826,9 @@ public abstract class AbstractServices {
 
     final ResWrap<AtomPropertyImpl> container = new ResWrap<AtomPropertyImpl>(
             URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX)
-                    + (version.compareTo(ODataServiceVersion.V40) >= 0
-                    ? entitySetName + "(" + entityId + ")/" + path
-                    : property.getType())),
+            + (version.compareTo(ODataServiceVersion.V40) >= 0
+            ? entitySetName + "(" + entityId + ")/" + path
+            : property.getType())),
             entryContainer.getMetadataETag(),
             property);
 
@@ -1791,9 +1836,9 @@ public abstract class AbstractServices {
             null,
             searchForValue
             ? IOUtils.toInputStream(
-                    container.getPayload().getValue() == null || container.getPayload().getValue().isNull()
-                    ? StringUtils.EMPTY
-                    : container.getPayload().getValue().asPrimitive().get(), Constants.ENCODING)
+            container.getPayload().getValue() == null || container.getPayload().getValue().isNull()
+            ? StringUtils.EMPTY
+            : container.getPayload().getValue().asPrimitive().get(), Constants.ENCODING)
             : utils.writeProperty(acceptType, container),
             Commons.getETag(Commons.getEntityBasePath(entitySetName, entityId), version),
             acceptType);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/fit/src/main/java/org/apache/olingo/fit/V3PrimitiveKeys.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/V3PrimitiveKeys.java b/fit/src/main/java/org/apache/olingo/fit/V3PrimitiveKeys.java
new file mode 100644
index 0000000..3b159af
--- /dev/null
+++ b/fit/src/main/java/org/apache/olingo/fit/V3PrimitiveKeys.java
@@ -0,0 +1,55 @@
+/*
+ * 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.fit;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.olingo.fit.utils.Accept;
+import org.apache.olingo.fit.utils.FSManager;
+import org.springframework.stereotype.Service;
+
+@Service
+@Path("/V30/PrimitiveKeys.svc")
+public class V3PrimitiveKeys extends V3Services {
+
+  public V3PrimitiveKeys() throws Exception {
+    super();
+  }
+
+  /**
+   * Provide sample large metadata.
+   *
+   * @return metadata.
+   */
+  @GET
+  @Path("/$metadata")
+  @Produces(MediaType.APPLICATION_XML)
+  @Override
+  public Response getMetadata() {
+    try {
+      return xml.createResponse(
+              null, FSManager.instance(version).readFile("primitiveKeysMetadata", Accept.XML), null, Accept.XML);
+    } catch (Exception e) {
+      return xml.createFaultResponse(Accept.XML.toString(version), e);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/fit/src/main/resources/V30/Driver/'2'/entity.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V30/Driver/'2'/entity.xml b/fit/src/main/resources/V30/Driver/'2'/entity.xml
new file mode 100644
index 0000000..777a62b
--- /dev/null
+++ b/fit/src/main/resources/V30/Driver/'2'/entity.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+    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.
+
+-->
+<entry xml:base="http://localhost:8080/DefaultService.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
+  <id>http://localhost:8080/DefaultService.svc/Driver('2')</id>
+  <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.Driver" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+  <link rel="edit" title="Driver" href="Driver('2')" />
+  <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/License" type="application/atom+xml;type=entry" title="License" href="Driver('2')/License" />
+  <title />
+  <updated>2014-05-13T14:07:58Z</updated>
+  <author>
+    <name />
+  </author>
+  <content type="application/xml">
+    <m:properties>
+      <d:Name>2</d:Name>
+      <d:BirthDate m:type="Edm.DateTime">2012-07-03T05:54:46.6217744</d:BirthDate>
+    </m:properties>
+  </content>
+</entry>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/fit/src/main/resources/V30/primitiveKeysMetadata.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V30/primitiveKeysMetadata.xml b/fit/src/main/resources/V30/primitiveKeysMetadata.xml
new file mode 100644
index 0000000..2e65aed
--- /dev/null
+++ b/fit/src/main/resources/V30/primitiveKeysMetadata.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+    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.
+
+-->
+<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
+  <edmx:DataServices m:DataServiceVersion="3.0" m:MaxDataServiceVersion="3.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
+    <Schema Namespace="Microsoft.Test.OData.Services.PrimitiveKeysService" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
+      <EntityType Name="EdmBinary">
+        <Key>
+          <PropertyRef Name="Id" />
+        </Key>
+        <Property Name="Id" Type="Edm.Binary" Nullable="false" />
+      </EntityType>
+      <EntityType Name="EdmBoolean">
+        <Key>
+          <PropertyRef Name="Id" />
+        </Key>
+        <Property Name="Id" Type="Edm.Boolean" Nullable="false" />
+      </EntityType>
+      <EntityType Name="EdmByte">
+        <Key>
+          <PropertyRef Name="Id" />
+        </Key>
+        <Property Name="Id" Type="Edm.Byte" Nullable="false" />
+      </EntityType>
+      <EntityType Name="EdmDateTime">
+        <Key>
+          <PropertyRef Name="Id" />
+        </Key>
+        <Property Name="Id" Type="Edm.DateTime" Nullable="false" />
+      </EntityType>
+      <EntityType Name="EdmDecimal">
+        <Key>
+          <PropertyRef Name="Id" />
+        </Key>
+        <Property Name="Id" Type="Edm.Decimal" Nullable="false" />
+      </EntityType>
+      <EntityType Name="EdmDouble">
+        <Key>
+          <PropertyRef Name="Id" />
+        </Key>
+        <Property Name="Id" Type="Edm.Double" Nullable="false" />
+      </EntityType>
+      <EntityType Name="EdmSingle">
+        <Key>
+          <PropertyRef Name="Id" />
+        </Key>
+        <Property Name="Id" Type="Edm.Single" Nullable="false" />
+      </EntityType>
+      <EntityType Name="EdmGuid">
+        <Key>
+          <PropertyRef Name="Id" />
+        </Key>
+        <Property Name="Id" Type="Edm.Guid" Nullable="false" />
+      </EntityType>
+      <EntityType Name="EdmInt16">
+        <Key>
+          <PropertyRef Name="Id" />
+        </Key>
+        <Property Name="Id" Type="Edm.Int16" Nullable="false" />
+      </EntityType>
+      <EntityType Name="EdmInt32">
+        <Key>
+          <PropertyRef Name="Id" />
+        </Key>
+        <Property Name="Id" Type="Edm.Int32" Nullable="false" />
+      </EntityType>
+      <EntityType Name="EdmInt64">
+        <Key>
+          <PropertyRef Name="Id" />
+        </Key>
+        <Property Name="Id" Type="Edm.Int64" Nullable="false" />
+      </EntityType>
+      <EntityType Name="EdmString">
+        <Key>
+          <PropertyRef Name="Id" />
+        </Key>
+        <Property Name="Id" Type="Edm.String" Nullable="false" />
+      </EntityType>
+      <EntityType Name="EdmTime">
+        <Key>
+          <PropertyRef Name="Id" />
+        </Key>
+        <Property Name="Id" Type="Edm.Time" Nullable="false" />
+      </EntityType>
+      <EntityType Name="EdmDateTimeOffset">
+        <Key>
+          <PropertyRef Name="Id" />
+        </Key>
+        <Property Name="Id" Type="Edm.DateTimeOffset" Nullable="false" />
+      </EntityType>
+      <EntityType Name="Folder">
+        <Key>
+          <PropertyRef Name="Id" />
+        </Key>
+        <Property Name="Id" Type="Edm.Int32" Nullable="false" />
+        <Property Name="Name" Type="Edm.String" />
+        <NavigationProperty Name="Parent" Relationship="Microsoft.Test.OData.Services.PrimitiveKeysService.Folder_Parent" ToRole="Parent" FromRole="Folder" />
+      </EntityType>
+      <Association Name="Folder_Parent">
+        <End Type="Microsoft.Test.OData.Services.PrimitiveKeysService.Folder" Role="Parent" Multiplicity="0..1" />
+        <End Type="Microsoft.Test.OData.Services.PrimitiveKeysService.Folder" Role="Folder" Multiplicity="*" />
+      </Association>
+      <EntityContainer Name="TestContext" m:IsDefaultEntityContainer="true">
+        <EntitySet Name="EdmBinarySet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmBinary" />
+        <EntitySet Name="EdmBooleanSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmBoolean" />
+        <EntitySet Name="EdmByteSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmByte" />
+        <EntitySet Name="EdmDateTimeSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmDateTime" />
+        <EntitySet Name="EdmDecimalSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmDecimal" />
+        <EntitySet Name="EdmDoubleSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmDouble" />
+        <EntitySet Name="EdmSingleSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmSingle" />
+        <EntitySet Name="EdmGuidSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmGuid" />
+        <EntitySet Name="EdmInt16Set" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmInt16" />
+        <EntitySet Name="EdmInt32Set" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmInt32" />
+        <EntitySet Name="EdmInt64Set" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmInt64" />
+        <EntitySet Name="EdmStringSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmString" />
+        <EntitySet Name="EdmTimeSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmTime" />
+        <EntitySet Name="EdmDateTimeOffsetSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmDateTimeOffset" />
+        <EntitySet Name="Folders" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.Folder" />
+        <AssociationSet Name="Folder_Parent" Association="Microsoft.Test.OData.Services.PrimitiveKeysService.Folder_Parent">
+          <End Role="Folder" EntitySet="Folders" />
+          <End Role="Parent" EntitySet="Folders" />
+        </AssociationSet>
+      </EntityContainer>
+      <Annotations Target="Microsoft.Test.OData.Services.PrimitiveKeysService.TestContext">
+        <ValueAnnotation Term="Com.Microsoft.Data.Services.Conventions.V1.UrlConventions" String="KeyAsSegment" />
+      </Annotations>
+    </Schema>
+  </edmx:DataServices>
+</edmx:Edmx>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/fit/src/main/webapp/WEB-INF/applicationContext.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/webapp/WEB-INF/applicationContext.xml b/fit/src/main/webapp/WEB-INF/applicationContext.xml
index f228583..53605e9 100644
--- a/fit/src/main/webapp/WEB-INF/applicationContext.xml
+++ b/fit/src/main/webapp/WEB-INF/applicationContext.xml
@@ -42,6 +42,7 @@
       <bean class="org.apache.olingo.fit.V3Services"/>
       <bean class="org.apache.olingo.fit.V3KeyAsSegment"/>
       <bean class="org.apache.olingo.fit.V3ActionOverloading"/>
+      <bean class="org.apache.olingo.fit.V3PrimitiveKeys"/>
       <bean class="org.apache.olingo.fit.V3OpenType"/>
       <bean class="org.apache.olingo.fit.V4Services"/>
       <bean class="org.apache.olingo.fit.V4KeyAsSegment"/>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/AbstractTestITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/AbstractTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/AbstractTestITCase.java
index e9afca9..73d5c32 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/AbstractTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/AbstractTestITCase.java
@@ -55,6 +55,8 @@ public abstract class AbstractTestITCase {
 
   protected static String testStaticServiceRootURL;
 
+  protected static String testPrimitiveKeysServiceRootURL;
+
   protected static String testKeyAsSegmentServiceRootURL;
 
   protected static String testActionOverloadingServiceRootURL;
@@ -74,6 +76,7 @@ public abstract class AbstractTestITCase {
   @BeforeClass
   public static void setUpODataServiceRoot() throws IOException {
     testStaticServiceRootURL = "http://localhost:9080/stub/StaticService/V30/Static.svc";
+    testPrimitiveKeysServiceRootURL = "http://localhost:9080/stub/StaticService/V30/PrimitiveKeys.svc";
     testKeyAsSegmentServiceRootURL = "http://localhost:9080/stub/StaticService/V30/KeyAsSegment.svc";
     testActionOverloadingServiceRootURL = "http://localhost:9080/stub/StaticService/V30/ActionOverloading.svc";
     testOpenTypeServiceRootURL = "http://localhost:9080/stub/StaticService/V30/OpenType.svc";

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/PropertyTestITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v3/PropertyTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/PropertyTestITCase.java
new file mode 100644
index 0000000..0296bac
--- /dev/null
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v3/PropertyTestITCase.java
@@ -0,0 +1,56 @@
+/*
+ * 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.fit.proxy.v3;
+
+import org.apache.olingo.ext.proxy.EntityContainerFactory;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.Driver;
+import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.Order;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+
+/**
+ * This is the unit test class to check actions overloading.
+ */
+public class PropertyTestITCase extends AbstractTestITCase {
+
+    @Test
+    public void nullNullableProperty() {
+        Order order = container.getOrder().get(-8);
+        order.setCustomerId(null);
+        container.flush();
+
+        assertNull(container.getOrder().get(-8).getCustomerId());
+    }
+
+    @Test
+    public void nullNonNullableProperty() {
+        Driver driver = container.getDriver().get("2");
+        driver.setBirthDate(null);
+
+        try {
+            container.flush();
+            fail();
+        } catch (IllegalStateException e) {
+            // ignore and detach all
+            EntityContainerFactory.getContext().detachAll();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/PropertyTestITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/PropertyTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/PropertyTestITCase.java
new file mode 100644
index 0000000..e8f7158
--- /dev/null
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/PropertyTestITCase.java
@@ -0,0 +1,56 @@
+/*
+ * 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.fit.proxy.v4;
+
+import org.apache.olingo.ext.proxy.EntityContainerFactory;
+import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.Customer;
+import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.StoredPI;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+
+/**
+ * This is the unit test class to check actions overloading.
+ */
+public class PropertyTestITCase extends AbstractTestITCase {
+
+  @Test
+  public void nullNullableProperty() {
+    Customer customer = container.getCustomers().get(1);
+    customer.setFirstName(null);
+    container.flush();
+
+    assertNull(container.getCustomers().get(1).getFirstName());
+  }
+
+  @Test
+  public void nullNonNullableProperty() {
+    final StoredPI storedPI = container.getStoredPIs().get(1000);
+    storedPI.setPIName(null);
+
+    try {
+      container.flush();
+      fail();
+    } catch (IllegalStateException e) {
+      // ignore and detach all
+      EntityContainerFactory.getContext().detachAll();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/PrimitiveValueTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/PrimitiveValueTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/PrimitiveValueTest.java
index 1438a3f..f902a0d 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/PrimitiveValueTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/PrimitiveValueTest.java
@@ -127,7 +127,7 @@ public class PrimitiveValueTest extends AbstractTest {
             setText(primitive).build();
     assertEquals(EdmPrimitiveTypeKind.Time, value.asPrimitive().getTypeKind());
     // performed cast to improve the check
-    assertEquals(primitive, value.asPrimitive().toCastValue(Duration.class).toString());
+    assertEquals("-780670.5063807", value.asPrimitive().toCastValue(BigDecimal.class).toString());
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDuration.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDuration.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDuration.java
index 87944c0..e39b8e7 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDuration.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDuration.java
@@ -25,7 +25,7 @@ import java.util.regex.Pattern;
 
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 
-public final class EdmDuration extends SingletonPrimitiveType {
+public class EdmDuration extends SingletonPrimitiveType {
 
   private static final Pattern PATTERN = Pattern.compile(
           "[-+]?P(?:(\\p{Digit}+)D)?(?:T(?:(\\p{Digit}+)H)?(?:(\\p{Digit}+)M)?"
@@ -81,6 +81,7 @@ public final class EdmDuration extends SingletonPrimitiveType {
       throw new EdmPrimitiveTypeException(
               "EdmPrimitiveTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType), e");
     } catch (final ClassCastException e) {
+      e.printStackTrace();
       throw new EdmPrimitiveTypeException(
               "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType), e");
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32518c1b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTime.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTime.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTime.java
index 8f52253..34ee020 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTime.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTime.java
@@ -18,15 +18,10 @@
  */
 package org.apache.olingo.commons.core.edm.primitivetype;
 
-import javax.xml.datatype.DatatypeFactory;
-import javax.xml.datatype.Duration;
-
-import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
-
 /**
  * Implementation of the EDM primitive type Time.
  */
-public final class EdmTime extends SingletonPrimitiveType {
+public final class EdmTime extends EdmDuration {
 
   private static final EdmTime INSTANCE = new EdmTime();
 
@@ -38,45 +33,4 @@ public final class EdmTime extends SingletonPrimitiveType {
     uriPrefix = "time'";
     uriSuffix = "'";
   }
-
-  @Override
-  public Class<?> getDefaultType() {
-    return Duration.class;
-  }
-
-  @Override
-  protected <T> T internalValueOfString(final String value,
-          final Boolean isNullable, final Integer maxLength, final Integer precision,
-          final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
-
-    Duration duration = null;
-    try {
-      final DatatypeFactory dtFactory = DatatypeFactory.newInstance();
-      duration = dtFactory.newDuration(value);
-    } catch (Exception e) {
-      throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)", e);
-    }
-
-    if (returnType.isAssignableFrom(Duration.class)) {
-      return returnType.cast(duration);
-    } else {
-      throw new EdmPrimitiveTypeException(
-              "EdmPrimitiveTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType)");
-    }
-  }
-
-  @Override
-  protected <T> String internalValueToString(final T value,
-          final Boolean isNullable, final Integer maxLength, final Integer precision,
-          final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
-
-    if (value instanceof Duration) {
-      final Duration duration = (Duration) value;
-      return duration.toString();
-    } else {
-      throw new EdmPrimitiveTypeException(
-              "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass())");
-    }
-
-  }
 }