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 2013/12/05 13:31:11 UTC

[18/52] git commit: Implementation for navigation (readRelated)

Implementation for navigation (readRelated)


Project: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/commit/454e178e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/tree/454e178e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/diff/454e178e

Branch: refs/heads/master
Commit: 454e178ed8cef5f47df3047cb12c4c461c6a3200
Parents: 20d6f02
Author: Michael Bolz <mi...@apache.org>
Authored: Tue Nov 12 10:35:19 2013 +0100
Committer: Michael Bolz <mi...@apache.org>
Committed: Tue Nov 12 14:06:26 2013 +0100

----------------------------------------------------------------------
 .../annotation/ds/AnnotationInMemoryDs.java     | 126 ++++++++----
 .../annotation/ds/AnnotationValueAccess.java    |   9 +
 .../annotation/edm/AnnotationEdmProvider.java   |  15 +-
 .../core/annotation/edm/AnnotationHelper.java   | 203 ++++++++++++++-----
 .../odata2/ref/annotation/model/Building.java   |   4 +
 .../odata2/ref/annotation/model/Employee.java   |  13 +-
 .../odata2/ref/annotation/model/RefBase.java    |  32 ++-
 .../odata2/ref/annotation/model/Room.java       |   2 +-
 .../odata2/ref/annotation/model/Team.java       |  11 +-
 .../processor/AnnotationPocServiceFactory.java  |  28 ++-
 10 files changed, 320 insertions(+), 123 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/454e178e/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/AnnotationInMemoryDs.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/AnnotationInMemoryDs.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/AnnotationInMemoryDs.java
index bdf5d77..999b2ab 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/AnnotationInMemoryDs.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/AnnotationInMemoryDs.java
@@ -1,41 +1,43 @@
-/*******************************************************************************
- * 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
- * 
+/**
+ * *****************************************************************************
+ * 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.
- ******************************************************************************/
+ *
+ * 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.odata2.core.annotation.ds;
 
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
 import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
 import org.apache.olingo.odata2.api.data.ListsDataSource;
 import org.apache.olingo.odata2.api.edm.EdmEntitySet;
 import org.apache.olingo.odata2.api.edm.EdmException;
 import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
 import org.apache.olingo.odata2.api.exception.ODataApplicationException;
 import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
 import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
 import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
 import org.apache.olingo.odata2.core.annotation.edm.ClassHelper;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
 
 public class AnnotationInMemoryDs implements ListsDataSource {
 
@@ -62,7 +64,7 @@ public class AnnotationInMemoryDs implements ListsDataSource {
       dataStores.put(entityType.name(), dhs);
     }
   }
-  
+
   public <T> DataStore<T> getDataStore(Class<T> clazz) {
     return DataStore.createInMemory(clazz);
   }
@@ -82,25 +84,24 @@ public class AnnotationInMemoryDs implements ListsDataSource {
   }
 
   @Override
-  public Object readData(EdmEntitySet entitySet, Map<String, Object> keys) 
-      throws ODataNotFoundException, EdmException, ODataApplicationException {
+  public Object readData(EdmEntitySet entitySet, Map<String, Object> keys)
+          throws ODataNotFoundException, EdmException, ODataApplicationException {
     final String name = entitySet.getEntityType().getName();
 
     DataStore<Object> store = dataStores.get(name);
     if (store != null) {
-        Object keyInstance = store.createInstance();
-        setKeyFields(keyInstance, keys.values().toArray());
+      Object keyInstance = store.createInstance();
+      ANNOTATION_HELPER.setKeyFields(keyInstance, keys.values().toArray());
 
-        Object result = store.read(keyInstance);
-        if (result != null) {
-          return result;
-        }
+      Object result = store.read(keyInstance);
+      if (result != null) {
+        return result;
+      }
     }
 
     throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
   }
 
-  
   @Override
   public Object readData(EdmFunctionImport function, Map<String, Object> parameters, Map<String, Object> keys)
           throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
@@ -111,14 +112,46 @@ public class AnnotationInMemoryDs implements ListsDataSource {
   public Object readRelatedData(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
           Map<String, Object> targetKeys)
           throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-    final Object data;
+
     if (targetKeys.isEmpty()) {
-      data = this.readData(targetEntitySet);
+      String sourceName = sourceEntitySet.getEntityType().getName();
+      DataStore sourceStore = dataStores.get(sourceName);
+
+      String targetName = targetEntitySet.getEntityType().getName();
+      DataStore targetStore = dataStores.get(targetName);
+
+      Field sourceFieldAtTarget = extractSourceField(sourceStore, targetStore);
+      if (sourceFieldAtTarget == null) {
+        throw new ODataRuntimeException("Missing source field for related data.");
+      }
+
+      Collection targetData = targetStore.read();
+      List resultData = new ArrayList();
+      for (Object targetInstance : targetData) {
+        Object targetNavigationInstance = getValue(sourceFieldAtTarget, targetInstance);
+        if(targetNavigationInstance instanceof Collection) {
+          Collection c = (Collection) targetNavigationInstance;
+          for (Object object : c) {
+            if (ANNOTATION_HELPER.keyMatch(sourceData, object)) {
+              resultData.add(targetInstance);
+            }
+          }
+        } else if (ANNOTATION_HELPER.keyMatch(sourceData, targetNavigationInstance)) {
+          resultData.add(targetInstance);
+        }
+      }
+      
+      EdmNavigationProperty navProperty = sourceFieldAtTarget.getAnnotation(EdmNavigationProperty.class);
+      if(navProperty.from().multiplicity() == EdmMultiplicity.ONE) {
+        if(resultData.isEmpty()) {
+          return null;
+        }
+        return resultData.get(0);
+      }
+      return resultData;
     } else {
-      data = this.readData(targetEntitySet, targetKeys);
+      throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
     }
-
-    return data;
   }
 
   @Override
@@ -168,18 +201,27 @@ public class AnnotationInMemoryDs implements ListsDataSource {
           throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
     throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
   }
-  
 
-  private <T> T setKeyFields(T instance, Object[] keyValues) {
-    List<Field> fields = ANNOTATION_HELPER.getAnnotatedFields(instance, EdmKey.class);
-    if (fields.size() != keyValues.length) {
-      throw new IllegalStateException("Wrong amount of key properties. Expected read keys = "
-              + fields + " given key predicates = " + Arrays.toString(keyValues));
+  private Object getValue(Field field, Object instance) {
+    try {
+      boolean access = field.isAccessible();
+      field.setAccessible(true);
+      Object value = field.get(instance);
+      field.setAccessible(access);
+      return value;
+    } catch (IllegalArgumentException e) {
+      throw new ODataRuntimeException("Error for getting value of field '"
+              + field + "' at instance '" + instance + "'.", e);
+    } catch (IllegalAccessException e) {
+      throw new ODataRuntimeException("Error for getting value of field '"
+              + field + "' at instance '" + instance + "'.", e);
     }
-    
-    String propertyName = ANNOTATION_HELPER.getCanonicalName(fields.get(0));
-    ANNOTATION_HELPER.setValueForProperty(instance, propertyName, keyValues[0]);
+  }
 
-    return instance;
+  private Field extractSourceField(DataStore sourceStore, DataStore targetStore) {
+    Class sourceDataTypeClass = sourceStore.getDataTypeClass();
+    Class targetDataTypeClass = targetStore.getDataTypeClass();
+    
+    return ANNOTATION_HELPER.getCommonNavigationFieldFromTarget(sourceDataTypeClass, targetDataTypeClass);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/454e178e/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/AnnotationValueAccess.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/AnnotationValueAccess.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/AnnotationValueAccess.java
index 2c8ac96..5963131 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/AnnotationValueAccess.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/AnnotationValueAccess.java
@@ -18,6 +18,7 @@
  ******************************************************************************/
 package org.apache.olingo.odata2.core.annotation.ds;
 
+import java.util.Collection;
 import org.apache.olingo.odata2.api.data.ValueAccess;
 import org.apache.olingo.odata2.api.edm.EdmMapping;
 import org.apache.olingo.odata2.api.edm.EdmProperty;
@@ -39,6 +40,14 @@ public class AnnotationValueAccess implements ValueAccess {
    */
   @Override
   public <T> Object getPropertyValue(final T data, final EdmProperty property) throws ODataException {
+    if(data instanceof Collection) {
+      Collection c = (Collection) data;
+      for (Object object : c) {
+        if(annotationHelper.isEdmAnnotated(data)) {
+          return annotationHelper.getValueForProperty(data, property.getName());
+        }
+      }
+    }
     if(annotationHelper.isEdmAnnotated(data)) {
       return annotationHelper.getValueForProperty(data, property.getName());
     }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/454e178e/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
index 03cec0b..6fb69b7 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
@@ -457,17 +457,20 @@ public class AnnotationEdmProvider extends EdmProvider {
 
     private Property createComplexProperty(EdmProperty ep, Field field, String defaultNamespace) {
       ComplexProperty cp = new ComplexProperty();
+      // settings from property
       String entityName = ep.name();
       if (entityName.isEmpty()) {
         entityName = getCanonicalName(field);
       }
       cp.setName(entityName);
-      //
-      String entityNamespace = ep.namespace();
-      if (entityNamespace.isEmpty()) {
-        entityNamespace = defaultNamespace;
-      }
-      cp.setType(new FullQualifiedName(entityNamespace, entityName));
+      
+      // settings from related complex entity
+      EdmComplexEntity ece = field.getType().getAnnotation(EdmComplexEntity.class);
+      String complexEntityNamespace = ece.namespace();
+      if (complexEntityNamespace.isEmpty()) {
+        complexEntityNamespace = defaultNamespace;
+      }
+      cp.setType(new FullQualifiedName(complexEntityNamespace, ece.name()));
 
       return cp;
     }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/454e178e/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
index cc9cd6c..1e1d31b 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
@@ -1,56 +1,131 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
+/**
+ * *****************************************************************************
+ * 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.
- ******************************************************************************/
+ *
+ * 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.odata2.core.annotation.edm;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import org.apache.olingo.odata2.api.annotation.edm.EdmComplexEntity;
 import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.EdmNavigationProperty;
 import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
 import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.core.annotation.ds.DataStore;
 import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
 
 /**
  *
  */
 public class AnnotationHelper {
-  
+
+  public boolean keyMatch(Object firstInstance, Object secondInstance) {
+    if (firstInstance == null || secondInstance == null) {
+      return false;
+    } else if (firstInstance.getClass() != secondInstance.getClass()) {
+      return false;
+    }
+
+    Map<String, Object> firstKeyFields = getValueForAnnotatedFields(firstInstance, EdmKey.class);
+    Map<String, Object> secondKeyFields = getValueForAnnotatedFields(secondInstance, EdmKey.class);
+
+    if (firstKeyFields.size() != secondKeyFields.size()) {
+      return false;
+    } else {
+      Set<Map.Entry<String, Object>> entries = firstKeyFields.entrySet();
+      for (Map.Entry<String, Object> entry : entries) {
+        Object firstKey = entry.getValue();
+        Object secondKey = secondKeyFields.get(entry.getKey());
+        if (!isEqual(firstKey, secondKey)) {
+          return false;
+        }
+      }
+      return true;
+    }
+  }
+
+  private boolean isEqual(Object firstKey, Object secondKey) {
+    if (firstKey == null) {
+      if (secondKey == null) {
+        return true;
+      } else {
+        return secondKey.equals(firstKey);
+      }
+    } else {
+      return firstKey.equals(secondKey);
+    }
+  }
+
   public static final class ODataAnnotationException extends ODataException {
+
     public ODataAnnotationException(String message) {
       super(message);
     }
   }
   
+  public <T> T setKeyFields(T instance, Object[] keyValues) {
+    List<Field> fields = getAnnotatedFields(instance, EdmKey.class);
+    if (fields.size() != keyValues.length) {
+      throw new IllegalStateException("Wrong amount of key properties. Expected read keys = "
+              + fields + " given key predicates = " + Arrays.toString(keyValues));
+    }
+
+    String propertyName = getCanonicalName(fields.get(0));
+    setValueForProperty(instance, propertyName, keyValues[0]);
+
+    return instance;
+  }
+
+  
+  public Field getCommonNavigationFieldFromTarget(Class<?> sourceClass, Class<?> targetClass) {
+    List<Field> sourceFields = getAnnotatedFields(sourceClass, EdmNavigationProperty.class);
+    List<Field> targetFields = getAnnotatedFields(targetClass, EdmNavigationProperty.class);
+
+    for (Field targetField : targetFields) {
+      for (Field sourcField : sourceFields) {
+        EdmNavigationProperty sourceNav = sourcField.getAnnotation(EdmNavigationProperty.class);
+        EdmNavigationProperty targetNav = targetField.getAnnotation(EdmNavigationProperty.class);
+        if (sourceNav.relationship().equals(targetNav.relationship())) {
+          return targetField;
+        }
+      }
+    }
+    return null;
+  }
+
+
   public Class<?> getFieldTypeForProperty(Object instance, String propertyName) throws ODataAnnotationException {
     if (instance == null) {
       return null;
     }
-    
+
     Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
-    if(field == null) {
-      throw new ODataAnnotationException("No field for property '" + propertyName 
+    if (field == null) {
+      throw new ODataAnnotationException("No field for property '" + propertyName
               + "' found at class '" + instance.getClass() + "'.");
     }
     return field.getType();
@@ -60,10 +135,10 @@ public class AnnotationHelper {
     if (instance == null) {
       return null;
     }
-    
+
     Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
-    if(field == null) {
-      throw new ODataAnnotationException("No field for property '" + propertyName 
+    if (field == null) {
+      throw new ODataAnnotationException("No field for property '" + propertyName
               + "' found at class '" + instance.getClass() + "'.");
     }
     return getFieldValue(instance, field);
@@ -72,7 +147,7 @@ public class AnnotationHelper {
   public void setValueForProperty(Object instance, String propertyName, Object propertyValue) {
     if (instance != null) {
       Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
-      if(field != null) {
+      if (field != null) {
         setFieldValue(instance, field, propertyValue);
       }
     }
@@ -103,10 +178,8 @@ public class AnnotationHelper {
 //
 //    return null;
 //  }
-
-
-  private Field getFieldForPropertyName(Object instance, String propertyName, 
-      Class<?> resultClass, boolean inherited) {
+  private Field getFieldForPropertyName(Object instance, String propertyName,
+          Class<?> resultClass, boolean inherited) {
     if (instance == null) {
       return null;
     }
@@ -115,9 +188,9 @@ public class AnnotationHelper {
     for (Field field : fields) {
       EdmProperty property = field.getAnnotation(EdmProperty.class);
       if (property != null) {
-        if(property.name().isEmpty() && getCanonicalName(field).equals(propertyName)) {
+        if (property.name().isEmpty() && getCanonicalName(field).equals(propertyName)) {
           return field;
-        } else if(property.name().equals(propertyName)) {
+        } else if (property.name().equals(propertyName)) {
           return field;
         }
       }
@@ -131,7 +204,6 @@ public class AnnotationHelper {
     return null;
   }
 
-  
   public Object getValueForField(Object instance, String fieldName, Class<? extends Annotation> annotation) {
     if (instance == null) {
       return null;
@@ -147,7 +219,7 @@ public class AnnotationHelper {
   }
 
   private Object getValueForField(Object instance, Class<?> resultClass,
-      Class<? extends Annotation> annotation, boolean inherited) {
+          Class<? extends Annotation> annotation, boolean inherited) {
     return getValueForField(instance, null, resultClass, annotation, inherited);
   }
 
@@ -155,16 +227,16 @@ public class AnnotationHelper {
           Class<? extends Annotation> annotation) {
     return getValueForAnnotatedFields(instance, instance.getClass(), annotation, true);
   }
-    
+
   private Map<String, Object> getValueForAnnotatedFields(Object instance, Class<?> resultClass,
-    Class<? extends Annotation> annotation, boolean inherited) {
+          Class<? extends Annotation> annotation, boolean inherited) {
     if (instance == null) {
       return null;
     }
 
     Field[] fields = resultClass.getDeclaredFields();
     Map<String, Object> fieldName2Value = new HashMap<String, Object>();
-    
+
     for (Field field : fields) {
       if (field.getAnnotation(annotation) != null) {
         Object value = getFieldValue(instance, field);
@@ -181,41 +253,48 @@ public class AnnotationHelper {
     return fieldName2Value;
   }
 
-  public void setValuesToAnnotatedFields(Map<String, Object> fieldName2Value, Object instance, 
+  public void setValuesToAnnotatedFields(Map<String, Object> fieldName2Value, Object instance,
           Class<? extends Annotation> annotation) {
-    List<Field> fields = getAnnotatedFields(instance, instance.getClass(), annotation, true);
-    
+    List<Field> fields = getAnnotatedFields(instance, annotation);
+
     // XXX: refactore
     for (Field field : fields) {
       final String canonicalName = getCanonicalName(field);
-      if(fieldName2Value.containsKey(canonicalName)) {
+      if (fieldName2Value.containsKey(canonicalName)) {
         Object value = fieldName2Value.get(canonicalName);
         setFieldValue(instance, field, value);
       }
     }
   }
-          
+
   public List<Field> getAnnotatedFields(Object instance, Class<? extends Annotation> annotation) {
-    return getAnnotatedFields(instance, instance.getClass(), annotation, true);
-  } 
-  
+    if(instance == null) {
+      return null;
+    }
+    return getAnnotatedFields(instance.getClass(), annotation, true);
+  }
+
+  public List<Field> getAnnotatedFields(Class<?> fieldClass, Class<? extends Annotation> annotation) {
+    return getAnnotatedFields(fieldClass, annotation, true);
+  }
+
   /**
-   * 
+   *
    * @param instance
    * @param resultClass
    * @param annotation
    * @param inherited
-   * @return 
+   * @return
    */
-  private List<Field> getAnnotatedFields(Object instance, Class<?> resultClass,
-    Class<? extends Annotation> annotation, boolean inherited) {
-    if (instance == null) {
+  private List<Field> getAnnotatedFields(Class<?> resultClass,
+          Class<? extends Annotation> annotation, boolean inherited) {
+    if (resultClass == null) {
       return null;
     }
 
     Field[] fields = resultClass.getDeclaredFields();
     List<Field> annotatedFields = new ArrayList<Field>();
-    
+
     for (Field field : fields) {
       if (field.getAnnotation(annotation) != null) {
         annotatedFields.add(field);
@@ -224,7 +303,7 @@ public class AnnotationHelper {
 
     Class<?> superClass = resultClass.getSuperclass();
     if (inherited && superClass != Object.class) {
-      List<Field> tmp = getAnnotatedFields(instance, superClass, annotation, true);
+      List<Field> tmp = getAnnotatedFields(superClass, annotation, true);
       annotatedFields.addAll(tmp);
     }
 
@@ -232,7 +311,7 @@ public class AnnotationHelper {
   }
 
   private Object getValueForField(Object instance, String fieldName, Class<?> resultClass,
-      Class<? extends Annotation> annotation, boolean inherited) {
+          Class<? extends Annotation> annotation, boolean inherited) {
     if (instance == null) {
       return null;
     }
@@ -240,7 +319,7 @@ public class AnnotationHelper {
     Field[] fields = resultClass.getDeclaredFields();
     for (Field field : fields) {
       if (field.getAnnotation(annotation) != null
-          && (fieldName == null || field.getName().equals(fieldName))) {
+              && (fieldName == null || field.getName().equals(fieldName))) {
         return getFieldValue(instance, field);
       }
     }
@@ -269,6 +348,11 @@ public class AnnotationHelper {
 
   private void setFieldValue(Object instance, Field field, Object propertyValue) {
     try {
+      if (propertyValue != null
+              && field.getType() != propertyValue.getClass()
+              && propertyValue.getClass() == String.class) {
+        propertyValue = convert(field, (String) propertyValue);
+      }
       boolean access = field.isAccessible();
       field.setAccessible(true);
       field.set(instance, propertyValue);
@@ -280,7 +364,18 @@ public class AnnotationHelper {
     }
   }
 
-  
+  public Object convert(Field field, String propertyValue) {
+    Class fieldClass = field.getType();
+    try {
+      EdmProperty property = field.getAnnotation(EdmProperty.class);
+      EdmSimpleTypeKind type = property.type();
+      return type.getEdmSimpleTypeInstance().valueOfString(propertyValue,
+              EdmLiteralKind.DEFAULT, null, fieldClass);
+    } catch (EdmSimpleTypeException ex) {
+      throw new ODataRuntimeException(ex);
+    }
+  }
+
   public boolean isEdmAnnotated(Object object) {
     if (object == null) {
       return false;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/454e178e/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
index 59a8eb8..66adb24 100644
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Building.java
@@ -69,6 +69,10 @@ public class Building {
     }
   }
 
+  public void addRoom(Room room) {
+    rooms.add(room);
+  }
+  
   public List<Room> getRooms() {
     return rooms;
   }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/454e178e/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
index 76c4474..5092067 100644
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Employee.java
@@ -37,7 +37,7 @@ public class Employee {
   private static int counter = 1;
   @EdmKey
   @EdmProperty(name="EmployeeId", type = EdmSimpleTypeKind.String)
-  private int employeeId;
+  private String employeeId;
   @EdmProperty(name="EmployeeName")
   private String employeeName;
   @EdmProperty
@@ -46,6 +46,10 @@ public class Employee {
           from = @NavigationEnd(role="r_Employees", multiplicity = EdmMultiplicity.MANY))//,
 //          to = @NavigationEnd(type = "Manager"))
   private Manager manager;
+  @EdmNavigationProperty(name = "ne_Team", relationship="TeamEmployees", 
+          from = @NavigationEnd(role = "r_Employees", type = "Employee", multiplicity = EdmMultiplicity.MANY),
+          to = @NavigationEnd(role = "r_Team",  type = "Team")
+  )
   private Team team;
   private Room room;
   private String imageType;
@@ -56,7 +60,7 @@ public class Employee {
   private Location location;
 
   public String getId() {
-    return Integer.toString(employeeId);
+    return employeeId;
   }
 
   public void setEmployeeName(final String employeeName) {
@@ -152,7 +156,10 @@ public class Employee {
 
   @Override
   public int hashCode() {
-    return employeeId;
+    if(employeeId == null) {
+      return 0;
+    }
+    return employeeId.hashCode();
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/454e178e/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
index fef6317..5f40d1e 100644
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/RefBase.java
@@ -32,14 +32,14 @@ public abstract class RefBase {
   protected String name;
   @EdmProperty(name="Id", type = EdmSimpleTypeKind.String)
   @EdmKey
-  protected int id;
+  protected String id;
 
   public String getName() {
     return name;
   }
 
   public String getId() {
-    return Integer.toString(id);
+    return id;
   }
 
   public void setName(String name) {
@@ -47,6 +47,32 @@ public abstract class RefBase {
   }
 
   public void setId(int id) {
-    this.id = id;
+    this.id = String.valueOf(id);
+  }
+
+  @Override
+  public int hashCode() {
+    if(id == null) {
+      return -1;
+    }
+    return id.hashCode();
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == null) {
+      return false;
+    }
+    if (getClass() != obj.getClass()) {
+      return false;
+    }
+    final RefBase other = (RefBase) obj;
+    if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
+      return false;
+    }
+    if ((this.id == null) ? (other.id != null) : !this.id.equals(other.id)) {
+      return false;
+    }
+    return true;
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/454e178e/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
index c2e68fa..56e7e19 100644
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Room.java
@@ -75,7 +75,7 @@ public class Room extends RefBase {
 
   @Override
   public int hashCode() {
-    return id;
+    return super.hashCode();
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/454e178e/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
index d851428..6936517 100644
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Team.java
@@ -35,9 +35,10 @@ import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
 public class Team extends RefBase {
   @EdmProperty(type = EdmSimpleTypeKind.Boolean)
   private Boolean isScrumTeam;
-  @EdmNavigationProperty(name = "ne_Teams", relationship="TeamEmployees", 
-          from = @NavigationEnd(role = "r_Team",  type = "Team"),
-          to = @NavigationEnd(role = "r_Employees", type = "Employee", multiplicity = EdmMultiplicity.MANY))
+  @EdmNavigationProperty(name = "nt_Employees", relationship="TeamEmployees", 
+//          from = @NavigationEnd(role = "r_Team",  type = "Team"),
+          to = @NavigationEnd(role = "r_Employees", type = "Employee", multiplicity = EdmMultiplicity.MANY)
+  )
   private List<Employee> employees = new ArrayList<Employee>();
 
   public Boolean isScrumTeam() {
@@ -58,7 +59,7 @@ public class Team extends RefBase {
 
   @Override
   public int hashCode() {
-    return id;
+    return super.hashCode();
   }
 
   @Override
@@ -71,4 +72,4 @@ public class Team extends RefBase {
   public String toString() {
     return "{\"Id\":\"" + id + "\",\"Name\":\"" + name + "\",\"IsScrumTeam\":" + isScrumTeam + "}";
   }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/454e178e/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java
index 2617df0..eb1c252 100644
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/processor/AnnotationPocServiceFactory.java
@@ -112,10 +112,14 @@ public class AnnotationPocServiceFactory extends ODataServiceFactory {
     teamDs.create(createTeam("Team Zeta", true));
 
     DataStore<Building> buildingsDs = dataSource.getDataStore(Building.class);
-    buildingsDs.create(createBuilding("Red Building"));
-    buildingsDs.create(createBuilding("Green Building"));
-    buildingsDs.create(createBuilding("Blue Building"));
-    buildingsDs.create(createBuilding("Yellow Building"));
+    Building redBuilding = createBuilding("Red Building");
+    buildingsDs.create(redBuilding);
+    Building greenBuilding = createBuilding("Green Building");
+    buildingsDs.create(greenBuilding);
+    Building blueBuilding = createBuilding("Blue Building");
+    buildingsDs.create(blueBuilding);
+    Building yellowBuilding = createBuilding("Yellow Building");
+    buildingsDs.create(yellowBuilding);
 
     DataStore<Photo> photoDs = dataSource.getDataStore(Photo.class);
     photoDs.create(createPhoto("Small picture"));
@@ -123,10 +127,12 @@ public class AnnotationPocServiceFactory extends ODataServiceFactory {
     photoDs.create(createPhoto("Big picture"));
 
     DataStore<Room> roomDs = dataSource.getDataStore(Room.class);
-    roomDs.create(createRoom("Tiny room", 5, 1));
-    roomDs.create(createRoom("Small room", 20, 1));
-    roomDs.create(createRoom("Big room", 40, 1));
-    roomDs.create(createRoom("Huge room", 120, 1));
+    roomDs.create(createRoom("Tiny red room", 5, 1, redBuilding));
+    roomDs.create(createRoom("Small red room", 20, 1, redBuilding));
+    roomDs.create(createRoom("Small green room", 20, 1, greenBuilding));
+    roomDs.create(createRoom("Big blue room", 40, 1, blueBuilding));
+    roomDs.create(createRoom("Huge blue room", 120, 1, blueBuilding));
+    roomDs.create(createRoom("Huge yellow room", 120, 1, yellowBuilding));
   }
 
   private Team createTeam(String teamName, boolean isScrumTeam) {
@@ -151,11 +157,15 @@ public class AnnotationPocServiceFactory extends ODataServiceFactory {
     return p;
   }
 
-  private Room createRoom(String name, int seats, int version) {
+  private Room createRoom(String name, int seats, int version, Building building) {
     Room r = new Room();
     r.setName(name);
     r.setSeats(seats);
     r.setVersion(version);
+    r.setBuilding(building);
+    
+    building.addRoom(r);
+    
     return r;
   }
 }