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:17 UTC

[24/52] git commit: Added support for multiple 'EdmKey' annotations

Added support for multiple 'EdmKey' annotations


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/b7e7ee0d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/tree/b7e7ee0d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/diff/b7e7ee0d

Branch: refs/heads/master
Commit: b7e7ee0dff43353164816c3210ff3803fd88a634
Parents: a8ff9e2
Author: Michael Bolz <mi...@apache.org>
Authored: Fri Nov 15 09:17:32 2013 +0100
Committer: Michael Bolz <mi...@apache.org>
Committed: Fri Nov 15 12:54:37 2013 +0100

----------------------------------------------------------------------
 .../annotation/data/AnnotationInMemoryDs.java   | 272 +++++++++++++++++++
 .../annotation/data/AnnotationValueAccess.java  | 108 ++++++++
 .../annotation/data/BeanPropertyAccess.java     | 186 +++++++++++++
 .../core/annotation/data/DataSourceHolder.java  | 212 +++++++++++++++
 .../odata2/core/annotation/data/DataStore.java  | 182 +++++++++++++
 .../annotation/ds/AnnotationInMemoryDs.java     | 255 -----------------
 .../annotation/ds/AnnotationValueAccess.java    | 108 --------
 .../core/annotation/ds/BeanPropertyAccess.java  | 186 -------------
 .../core/annotation/ds/DataSourceHolder.java    | 212 ---------------
 .../odata2/core/annotation/ds/DataStore.java    | 166 -----------
 .../annotation/edm/AnnotationEdmProvider.java   |  19 +-
 .../core/annotation/edm/AnnotationHelper.java   |  57 +++-
 .../processor/AnnotationProcessor.java          |   2 +-
 .../data/AnnotationsInMemoryDsTest.java         | 157 +++++++++++
 .../edm/AnnotationEdmProviderTest.java          |  54 +++-
 .../odata2/core/annotation/model/Building.java  |  17 +-
 .../odata2/core/annotation/model/Photo.java     | 101 ++++---
 .../core/annotation/model/ResourceHelper.java   |  64 +++++
 .../odata2/ref/annotation/model/Photo.java      |   3 +-
 .../processor/AnnotationPocServiceFactory.java  |  11 +-
 .../src/main/webapp/index.jsp                   |   8 +-
 .../olingo/odata2/fit/ref/AbstractRefTest.java  |   2 +-
 .../AbstractContentNegotiationTest.java         |   2 +-
 .../ref/processor/ScenarioServiceFactory.java   |   2 +-
 .../olingo/odata2/ref/read/EntitySetTest.java   |   2 +-
 .../olingo/odata2/ref/read/EntityTest.java      |   2 +-
 26 files changed, 1364 insertions(+), 1026 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
new file mode 100644
index 0000000..b2f2618
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationInMemoryDs.java
@@ -0,0 +1,272 @@
+/**
+ * *****************************************************************************
+ * 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.odata2.core.annotation.data;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
+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 {
+
+  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
+  private final Map<String, DataStore<Object>> dataStores = new HashMap<String, DataStore<Object>>();
+
+  public AnnotationInMemoryDs(String packageToScan) {
+    List<Class<?>> foundClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
+      @Override
+      public boolean isClassValid(Class<?> c) {
+        return null != c.getAnnotation(EdmEntityType.class);
+      }
+    });
+
+    init(foundClasses);
+  }
+
+  @SuppressWarnings("unchecked")
+  private void init(List<Class<?>> foundClasses) {
+    for (Class<?> clz : foundClasses) {
+
+      DataStore<Object> dhs = (DataStore<Object>) DataStore.createInMemory(clz);
+      EdmEntityType entityType = clz.getAnnotation(EdmEntityType.class);
+      dataStores.put(entityType.name(), dhs);
+    }
+  }
+
+  public <T> DataStore<T> getDataStore(Class<T> clazz) {
+    return DataStore.createInMemory(clazz);
+  }
+
+  @Override
+  public List<?> readData(EdmEntitySet entitySet) throws ODataNotImplementedException,
+          ODataNotFoundException, EdmException, ODataApplicationException {
+
+    DataStore<Object> holder = getDataStore(entitySet);
+    if (holder != null) {
+      return new ArrayList(holder.read());
+    }
+
+    throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+  }
+
+  @Override
+  public Object readData(EdmEntitySet entitySet, Map<String, Object> keys)
+          throws ODataNotFoundException, EdmException, ODataApplicationException {
+
+    DataStore<Object> store = getDataStore(entitySet);
+    if (store != null) {
+      Object keyInstance = store.createInstance();
+      ANNOTATION_HELPER.setKeyFields(keyInstance, keys);
+
+      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 {
+    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+  }
+
+  @Override
+  public Object readRelatedData(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+          Map<String, Object> targetKeys)
+          throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+
+    if (targetKeys.isEmpty()) {
+      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 {
+      throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+    }
+  }
+
+  @Override
+  public BinaryData readBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData)
+          throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+
+    Object data = ANNOTATION_HELPER.getValueForField(mediaLinkEntryData, EdmMediaResourceContent.class);
+    Object mimeType = ANNOTATION_HELPER.getValueForField(mediaLinkEntryData, EdmMediaResourceMimeType.class);
+
+    BinaryData db = new BinaryData((byte[])data, String.valueOf(mimeType));
+    return db;
+  }
+
+  @Override
+  public Object newDataObject(EdmEntitySet entitySet)
+          throws ODataNotImplementedException, EdmException, ODataApplicationException {
+
+    DataStore<Object> dataStore = getDataStore(entitySet);
+    if (dataStore != null) {
+      return dataStore.createInstance();
+    }
+
+    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+  }
+
+  @Override
+  public void writeBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData, BinaryData binaryData)
+          throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+
+  }
+
+  /**
+   * <p>Updates a single data object identified by the specified entity set and key fields of
+   * the data object.</p>
+   * @param entitySet the {@link EdmEntitySet} the object must correspond to
+   * @param data the data object of the new entity
+   * @return updated data object instance
+   * @throws org.apache.olingo.odata2.api.exception.ODataNotImplementedException
+   * @throws org.apache.olingo.odata2.api.edm.EdmException
+   * @throws org.apache.olingo.odata2.api.exception.ODataApplicationException
+   */
+  public Object updateData(EdmEntitySet entitySet, Object data)
+          throws ODataNotImplementedException, EdmException, ODataApplicationException {
+
+    DataStore<Object> dataStore = getDataStore(entitySet);
+    return dataStore.update(data);
+  }
+
+  @Override
+  public void deleteData(EdmEntitySet entitySet, Map<String, Object> keys)
+          throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+    DataStore<Object> dataStore = getDataStore(entitySet);
+    Object keyInstance = dataStore.createInstance();
+    ANNOTATION_HELPER.setKeyFields(keyInstance, keys);
+    dataStore.delete(keyInstance);
+  }
+
+  @Override
+  public void createData(EdmEntitySet entitySet, Object data)
+          throws ODataNotImplementedException, EdmException, ODataApplicationException {
+
+    DataStore<Object> dataStore = getDataStore(entitySet);
+    dataStore.create(data);
+  }
+
+  @Override
+  public void deleteRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+          Map<String, Object> targetKeys)
+          throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+  }
+
+  @Override
+  public void writeRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
+          Map<String, Object> targetKeys)
+          throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
+    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+  }
+
+
+  /**
+   * Returns corresponding DataStore for EdmEntitySet or if no data store is registered an
+   * ODataRuntimeException is thrown.
+   * Never returns NULL.
+   * 
+   * @param entitySet for which the corresponding DataStore is returned
+   * @return a DataStore object 
+   * @throws EdmException 
+   * @throws  ODataRuntimeException if no DataStore is found
+   */
+  private DataStore<Object> getDataStore(EdmEntitySet entitySet) throws EdmException {
+    final String name = entitySet.getEntityType().getName();
+    DataStore<Object> dataStore = dataStores.get(name);
+    if(dataStore == null) {
+      throw new ODataRuntimeException("No DataStore found for entity set '" + entitySet + "'.");
+    }
+    return dataStore;
+  }
+
+  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);
+    }
+  }
+
+  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/b7e7ee0d/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
new file mode 100644
index 0000000..6c65bf8
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/AnnotationValueAccess.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.data;
+
+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;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
+import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
+
+/**
+ *
+ */
+public class AnnotationValueAccess implements ValueAccess {
+  private final AnnotationHelper annotationHelper = new AnnotationHelper();
+  
+  /**
+   * Retrieves the value of an EDM property for the given data object.
+   * @param data     the Java data object
+   * @param property the requested {@link EdmProperty}
+   * @return the requested property value
+   */
+  @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());
+    }
+    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+  }
+
+  /**
+   * Sets the value of an EDM property for the given data object.
+   * @param data     the Java data object
+   * @param property the {@link EdmProperty}
+   * @param value    the new value of the property
+   */
+  @Override
+  public <T, V> void setPropertyValue(T data, final EdmProperty property, final V value) throws ODataException {
+    if(annotationHelper.isEdmAnnotated(data)) {
+      annotationHelper.setValueForProperty(data, property.getName(), value);
+    } else {
+      throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+    }
+  }
+
+  /**
+   * Retrieves the Java type of an EDM property for the given data object.
+   * @param data     the Java data object
+   * @param property the requested {@link EdmProperty}
+   * @return the requested Java type
+   */
+  public <T> Class<?> getPropertyType(final T data, final EdmProperty property) throws ODataException {
+    if(annotationHelper.isEdmAnnotated(data)) {
+      Class<?> fieldType = annotationHelper.getFieldTypeForProperty(data, property.getName());
+      if(fieldType == null) {
+        throw new ODataException("No field type found for property " + property);
+      }
+      return fieldType;
+    }
+    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+  }
+
+  /**
+   * Retrieves the value defined by a mapping object for the given data object.
+   * @param data     the Java data object
+   * @param mapping  the requested {@link EdmMapping}
+   * @return the requested value
+   */
+  public <T> Object getMappingValue(final T data, final EdmMapping mapping) throws ODataException {
+    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+  }
+
+  /**
+   * Sets the value defined by a mapping object for the given data object.
+   * @param data     the Java data object
+   * @param mapping  the {@link EdmMapping}
+   * @param value    the new value
+   */
+  public <T, V> void setMappingValue(T data, final EdmMapping mapping, final V value) throws ODataException {
+    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java
new file mode 100644
index 0000000..be3baac
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/BeanPropertyAccess.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.data;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+import org.apache.olingo.odata2.api.data.ValueAccess;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.exception.ODataHttpException;
+import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
+
+/**
+ * Data access.
+ */
+public class BeanPropertyAccess implements ValueAccess {
+
+  @Override
+  public <T> Object getPropertyValue(final T data, final EdmProperty property) throws ODataException {
+    return getValue(data, getGetterMethodName(property));
+  }
+
+  @Override
+  public <T, V> void setPropertyValue(T data, final EdmProperty property, final V value) throws ODataException {
+    final String methodName = getSetterMethodName(getGetterMethodName(property));
+    if (methodName != null) {
+      setValue(data, methodName, value);
+    }
+  }
+
+  @Override
+  public <T> Class<?> getPropertyType(final T data, final EdmProperty property) throws ODataException {
+    return getType(data, getGetterMethodName(property));
+  }
+
+  @Override
+  public <T> Object getMappingValue(final T data, final EdmMapping mapping) throws ODataException {
+    if (mapping != null && mapping.getMimeType() != null) {
+      return getValue(data, mapping.getMimeType());
+    }
+    return null;
+  }
+
+  @Override
+  public <T, V> void setMappingValue(T data, final EdmMapping mapping, final V value) throws ODataException {
+    if (mapping != null && mapping.getMimeType() != null) {
+      setValue(data, getSetterMethodName(mapping.getMimeType()), value);
+    }
+  }
+
+  private String getGetterMethodName(final EdmProperty property) throws EdmException {
+    final String prefix = isBooleanProperty(property) ? "is" : "get";
+    final String defaultMethodName = prefix + property.getName();
+    return property.getMapping() == null || property.getMapping().getInternalName() == null ?
+        defaultMethodName : property.getMapping().getInternalName();
+  }
+
+  private boolean isBooleanProperty(final EdmProperty property) throws EdmException {
+    return property.isSimple() 
+        && property.getType() == EdmSimpleTypeKind.Boolean.getEdmSimpleTypeInstance();
+  }
+
+  private String getSetterMethodName(final String getterMethodName) {
+    return getterMethodName.contains(".") ?
+        null : getterMethodName.replaceFirst("^is", "set").replaceFirst("^get", "set");
+  }
+
+  private <T> Object getValue(final T data, final String methodName) throws ODataNotFoundException {
+    Object dataObject = data;
+
+    for (final String method : methodName.split("\\.", -1)) {
+      if (dataObject != null) {
+        try {
+          dataObject = dataObject.getClass().getMethod(method).invoke(dataObject);
+        } catch (SecurityException e) {
+          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+        } catch (NoSuchMethodException e) {
+          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+        } catch (IllegalArgumentException e) {
+          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+        } catch (IllegalAccessException e) {
+          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+        } catch (InvocationTargetException e) {
+          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+        }
+      }
+    }
+
+    return dataObject;
+  }
+
+  private <T, V> void setValue(final T data, final String methodName, final V value)
+      throws ODataNotFoundException {
+    try {
+      boolean found = false;
+      for (final Method method : Arrays.asList(data.getClass().getMethods())) {
+        if (method.getName().equals(methodName)) {
+          found = true;
+          final Class<?> type = method.getParameterTypes()[0];
+          if (value == null) {
+            if (type.equals(byte.class) || type.equals(short.class) || type.equals(int.class)
+                || type.equals(long.class) || type.equals(char.class)) {
+              method.invoke(data, 0);
+            } else if (type.equals(float.class) || type.equals(double.class)) {
+              method.invoke(data, 0.0);
+            } else if (type.equals(boolean.class)) {
+              method.invoke(data, false);
+            } else {
+              method.invoke(data, value);
+            }
+          } else {
+            method.invoke(data, value);
+          }
+          break;
+        }
+      }
+      if (!found) {
+        throw new ODataNotFoundException(null);
+      }
+    } catch (SecurityException e) {
+      throw new ODataNotFoundException(null, e);
+    } catch (IllegalArgumentException e) {
+      throw new ODataNotFoundException(null, e);
+    } catch (IllegalAccessException e) {
+      throw new ODataNotFoundException(null, e);
+    } catch (InvocationTargetException e) {
+      throw new ODataNotFoundException(null, e);
+    }
+  }
+
+  private <T> Class<?> getType(final T data, final String methodName) throws ODataNotFoundException {
+    if (data == null) {
+      throw new ODataNotFoundException(ODataHttpException.COMMON);
+    }
+
+    Class<?> type = data.getClass();
+    for (final String method : methodName.split("\\.", -1)) {
+      try {
+        type = type.getMethod(method).getReturnType();
+        if (type.isPrimitive()) {
+          if (type == boolean.class) {
+            type = Boolean.class;
+          } else if (type == byte.class) {
+            type = Byte.class;
+          } else if (type == short.class) {
+            type = Short.class;
+          } else if (type == int.class) {
+            type = Integer.class;
+          } else if (type == long.class) {
+            type = Long.class;
+          } else if (type == float.class) {
+            type = Float.class;
+          } else if (type == double.class) {
+            type = Double.class;
+          }
+        }
+      } catch (final SecurityException e) {
+        throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+      } catch (final NoSuchMethodException e) {
+        throw new ODataNotFoundException(ODataHttpException.COMMON, e);
+      }
+    }
+    return type;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataSourceHolder.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataSourceHolder.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataSourceHolder.java
new file mode 100644
index 0000000..d4c6f98
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataSourceHolder.java
@@ -0,0 +1,212 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.data;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityCreate;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDataSource;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDelete;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityRead;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntitySetRead;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityUpdate;
+import org.apache.olingo.odata2.api.uri.KeyPredicate;
+import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
+
+/**
+ *
+ */
+public final class DataSourceHolder {
+
+  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
+  private static final Object[] EMPTY_ARRAY = new Object[0];
+  
+  private final String name;
+  private final Object dataSourceInstance;
+  private final Class<?> entityTypeClass;
+  private Method readMethod;
+  private Method createMethod;
+  private Method updateMethod;
+  private Method deleteMethod;
+  private Method readSetMethod;
+
+  public DataSourceHolder(Class<?> clz) {
+    EntityDataSource eds = clz.getAnnotation(EntityDataSource.class);
+    entityTypeClass = eds.entityType();
+    EdmEntityType entityType = entityTypeClass.getAnnotation(EdmEntityType.class);
+    if (entityType == null) {
+      throw new IllegalArgumentException("Missing EdmEntityType Annotation at class " + clz);
+    }
+
+    if (entityType.name().isEmpty()) {
+      name = ANNOTATION_HELPER.getCanonicalName(entityTypeClass);
+    } else {
+      name = entityType.name();
+    }
+    dataSourceInstance = createInstance(clz);
+    initMethods(clz);
+  }
+
+  private void initMethods(Class<?> clz) throws IllegalArgumentException, SecurityException {
+    Method[] methods = clz.getDeclaredMethods();
+    for (Method method : methods) {
+      EntityRead ec = method.getAnnotation(EntityRead.class);
+      if (ec != null) {
+        readMethod = method;
+      }
+      EntityCreate ep = method.getAnnotation(EntityCreate.class);
+      if (ep != null) {
+        createMethod = method;
+      }
+      EntityUpdate update = method.getAnnotation(EntityUpdate.class);
+      if (update != null) {
+        updateMethod = method;
+      }
+      EntityDelete delete = method.getAnnotation(EntityDelete.class);
+      if (delete != null) {
+        deleteMethod = method;
+      }
+      EntitySetRead readSet = method.getAnnotation(EntitySetRead.class);
+      if (readSet != null) {
+        readSetMethod = method;
+      }
+    }
+
+    validateMethods(clz);
+  }
+
+  private void validateMethods(Class<?> clz) throws IllegalArgumentException {
+    //
+    if (readMethod == null) {
+      throw new IllegalArgumentException("Missing " + EntityRead.class
+              + " annotation at " + EntityDataSource.class + " annotated class " + clz);
+    }
+    if (updateMethod == null) {
+      throw new IllegalArgumentException("Missing " + EntityUpdate.class
+              + " annotation at " + EntityDataSource.class + " annotated class " + clz);
+    }
+    if (createMethod == null) {
+      throw new IllegalArgumentException("Missing " + EntityCreate.class
+              + " annotation at " + EntityDataSource.class + " annotated class " + clz);
+    }
+    
+    if(readSetMethod != null) {
+      if(!Collection.class.isAssignableFrom(readSetMethod.getReturnType())) {
+        throw new IllegalArgumentException("Read set method must have a return type which is assignable to " 
+            + Collection.class + " but return type for annotated method " + readSetMethod + " is " 
+            + readSetMethod.getReturnType());
+      }
+    }
+  }
+
+  public Object readEntity(Object[] keyValues) {
+    if (readMethod.getParameterTypes().length != keyValues.length) {
+      throw new IllegalStateException("Wrong amount of key properties. Expected read keys = "
+              + Arrays.toString(readMethod.getParameterTypes()) + " given key predicates = " 
+              + Arrays.toString(keyValues));
+    }
+
+    return invoke(readMethod, keyValues);
+  }
+
+  public Object readEntity(List<KeyPredicate> keys) {
+    Object[] parameterKeys = mapParameterKeys(readMethod, keys);
+    return invoke(readMethod, parameterKeys);
+  }
+
+  private Object[] mapParameterKeys(Method method, List<KeyPredicate> keys) throws IllegalStateException {
+    if(method == null) {
+      return EMPTY_ARRAY;
+    }
+    Class<?>[] pTypes = method.getParameterTypes();
+    if (pTypes.length != keys.size()) {
+      throw new IllegalStateException("Wrong amount of key properties. Expected read keys = "
+              + Arrays.toString(pTypes) + " given key predicates = " + keys);
+    }
+    Object[] parameterKeys = new Object[pTypes.length];
+    int i = 0;
+    for (KeyPredicate keyPredicate : keys) {
+      if (matches(pTypes[i], keyPredicate)) {
+        parameterKeys[i] = keyPredicate.getLiteral();
+      }
+      i++;
+    }
+    return parameterKeys;
+  }
+
+  public Object createEntity(Object key) {
+    return invoke(createMethod, new Object[]{key});
+  }
+
+  public Object updateEntity(Object key) {
+    return invoke(updateMethod, new Object[]{key});
+  }
+
+  public Object deleteEntity(List<KeyPredicate> keys) {
+    Object[] parameterKeys = mapParameterKeys(deleteMethod, keys);
+    return invoke(deleteMethod, parameterKeys);
+  }
+
+  public Collection<?> readEntitySet() {
+    return (Collection<?>) invoke(readSetMethod, new Object[0]);
+  }
+
+  private Object invoke(Method m, Object[] objs) {
+    try {
+      return m.invoke(dataSourceInstance, objs);
+    } catch (Exception ex) {
+      return null;
+    }
+  }
+
+  public Object createEntityInstance() {
+    return createInstance(this.entityTypeClass);
+  }
+
+  private static Object createInstance(Class<?> clz) {
+    try {
+      return clz.newInstance();
+    } catch (Exception ex) {
+      return null;
+    }
+  }
+
+  public String getEntityName() {
+    return this.name;
+  }
+
+  public Class<?> getEntityTypeClass() {
+    return entityTypeClass;
+  }
+
+  @Override
+  public String toString() {
+    return "DataSourceHolder{" + "name=" + name + ", dataSourceInstance=" + dataSourceInstance + 
+            ", entityTypeClass=" + entityTypeClass + ", consumerMethod=" + readMethod + 
+            ", createMethod=" + createMethod + ", updateMethod=" + updateMethod + '}';
+  }
+
+  private boolean matches(Class<?> aClass, KeyPredicate type) {
+    return true;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
new file mode 100644
index 0000000..f8045f1
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/data/DataStore.java
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * 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.odata2.core.annotation.data;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityCreate;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDelete;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityRead;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntitySetRead;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityUpdate;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+/**
+ *
+ */
+public class DataStore<T> {
+
+  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
+  private final List<T> dataStore;
+  private final Class<T> dataTypeClass;
+
+  private int idCounter = 1;
+  
+  private static class InMemoryDataStore {
+    private static final Map<Class<?>, DataStore<?>> c2ds = new HashMap<Class<?>, DataStore<?>>();
+    @SuppressWarnings("unchecked")
+    static DataStore<?> getInstance(Class<?> clz) {
+      DataStore<?> ds = c2ds.get(clz);
+      if(ds == null) {
+        ds = new DataStore<Object>((Class<Object>) clz);
+        c2ds.put(clz, ds);
+      }
+      return ds;
+    }
+  }
+  
+  @SuppressWarnings("unchecked")
+  public static <T> DataStore<T> createInMemory(Class<T> clazz) {
+    return (DataStore<T>) InMemoryDataStore.getInstance(clazz);
+  }
+  
+  private DataStore(List<T> wrapStore, Class<T> clz) {
+    dataStore = wrapStore;
+    dataTypeClass = clz;
+  }
+
+  private DataStore(Class<T> clz) {
+    this(new ArrayList<T>(), clz);
+  }
+  
+  public Class<T> getDataTypeClass() {
+    return dataTypeClass;
+  }
+  
+  public T createInstance() {
+    try {
+      return dataTypeClass.newInstance();
+    } catch (InstantiationException e) {
+      throw new ODataRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
+    } catch (IllegalAccessException e) {
+      throw new ODataRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
+    }
+  }
+  
+  @EntityRead
+  public T read(T obj) {
+    List<Object> objKeys = getKeys(obj);
+    for (T stored : dataStore) {
+      if (objKeys.equals(getKeys(stored))) {
+        return stored;
+      }
+    }
+    return null;
+  }
+
+  @EntitySetRead
+  public Collection<T> read() {
+    return Collections.unmodifiableCollection(dataStore);
+  }
+
+  @EntityCreate
+  public T create(T object) throws DataStoreException {
+    createKeys(object);
+    dataStore.add(object);
+    return object;
+  }
+
+  @EntityUpdate
+  public T update(T object) {
+    T stored = read(object);
+    dataStore.remove(stored);
+    dataStore.add(object);
+    return object;
+  }
+
+  @EntityDelete
+  public T delete(T object) {
+    T stored = read(object);
+    if(stored != null) {    
+      dataStore.remove(stored);
+    }
+    return stored;
+  }
+  
+  private List<Object> getKeys(T object) {
+    Map<String, Object> keys = ANNOTATION_HELPER.getValueForAnnotatedFields(object, EdmKey.class);
+    
+    // XXX: list should be in a defined order -> better to create an 'Key' object which is comparable 
+    List<Object> keyList = new ArrayList(keys.values());
+    return keyList;
+  }
+  
+  private T createKeys(T object) throws DataStoreException {
+    List<Field> fields = ANNOTATION_HELPER.getAnnotatedFields(object, EdmKey.class);
+    if(fields.isEmpty()) {
+      throw new DataStoreException("No EdmKey annotated fields found for class " + object.getClass());
+    }
+    Map<String, Object> fieldName2KeyValue = new HashMap<String, Object>();
+    
+    for (Field field : fields) {
+      Object key = createKey(field);
+      fieldName2KeyValue.put(ANNOTATION_HELPER.getCanonicalName(field), key);
+    }
+    
+    ANNOTATION_HELPER.setValuesToAnnotatedFields(fieldName2KeyValue, object, EdmKey.class);
+    
+    return object;
+  }
+
+  private Object createKey(Field field) {
+    Class<?> type = field.getType();
+    
+    if(type == String.class) {
+      return String.valueOf(idCounter++);
+    } else if(type == Integer.class || type == int.class) {
+      return Integer.valueOf(idCounter++);
+    } else if(type == Long.class || type == long.class) {
+      return Long.valueOf(idCounter++);
+    }
+    
+    throw new UnsupportedOperationException("Automated key generation for type '" + type
+            + "' is not supported (caused on field '" + field + "').");
+  }
+  
+  public static class DataStoreException extends ODataApplicationException {
+
+    public DataStoreException(String message) {
+      this(message, null);
+    }
+
+    public DataStoreException(String message, Throwable cause) {
+      super(message, Locale.ENGLISH, cause);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/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
deleted file mode 100644
index a07765d..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/AnnotationInMemoryDs.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/**
- * *****************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
- * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
- * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
- *****************************************************************************
- */
-package org.apache.olingo.odata2.core.annotation.ds;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
-import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
-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 {
-
-  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
-  private final Map<String, DataStore<Object>> dataStores = new HashMap<String, DataStore<Object>>();
-
-  public AnnotationInMemoryDs(String packageToScan) {
-    List<Class<?>> foundClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
-      @Override
-      public boolean isClassValid(Class<?> c) {
-        return null != c.getAnnotation(EdmEntityType.class);
-      }
-    });
-
-    init(foundClasses);
-  }
-
-  @SuppressWarnings("unchecked")
-  private void init(List<Class<?>> foundClasses) {
-    for (Class<?> clz : foundClasses) {
-
-      DataStore<Object> dhs = (DataStore<Object>) DataStore.createInMemory(clz);
-      EdmEntityType entityType = clz.getAnnotation(EdmEntityType.class);
-      dataStores.put(entityType.name(), dhs);
-    }
-  }
-
-  public <T> DataStore<T> getDataStore(Class<T> clazz) {
-    return DataStore.createInMemory(clazz);
-  }
-
-  @Override
-  public List<?> readData(EdmEntitySet entitySet) throws ODataNotImplementedException,
-          ODataNotFoundException, EdmException, ODataApplicationException {
-
-    DataStore<Object> holder = getDataStore(entitySet);
-    if (holder != null) {
-      return new ArrayList(holder.read());
-    }
-
-    throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
-  }
-
-  @Override
-  public Object readData(EdmEntitySet entitySet, Map<String, Object> keys)
-          throws ODataNotFoundException, EdmException, ODataApplicationException {
-
-    DataStore<Object> store = getDataStore(entitySet);
-    if (store != null) {
-      Object keyInstance = store.createInstance();
-      ANNOTATION_HELPER.setKeyFields(keyInstance, keys.values().toArray());
-
-      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 {
-    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
-  }
-
-  @Override
-  public Object readRelatedData(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
-          Map<String, Object> targetKeys)
-          throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-
-    if (targetKeys.isEmpty()) {
-      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 {
-      throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
-    }
-  }
-
-  @Override
-  public BinaryData readBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData)
-          throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-
-    Object data = ANNOTATION_HELPER.getValueForField(mediaLinkEntryData, EdmMediaResourceContent.class);
-    Object mimeType = ANNOTATION_HELPER.getValueForField(mediaLinkEntryData, EdmMediaResourceMimeType.class);
-
-    BinaryData db = new BinaryData((byte[])data, String.valueOf(mimeType));
-    return db;
-  }
-
-  @Override
-  public Object newDataObject(EdmEntitySet entitySet)
-          throws ODataNotImplementedException, EdmException, ODataApplicationException {
-
-    DataStore<Object> dataStore = getDataStore(entitySet);
-    if (dataStore != null) {
-      return dataStore.createInstance();
-    }
-
-    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
-  }
-
-  @Override
-  public void writeBinaryData(EdmEntitySet entitySet, Object mediaLinkEntryData, BinaryData binaryData)
-          throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
-
-  }
-
-  @Override
-  public void deleteData(EdmEntitySet entitySet, Map<String, Object> keys)
-          throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-    DataStore<Object> dataStore = getDataStore(entitySet);
-    Object keyInstance = dataStore.createInstance();
-    ANNOTATION_HELPER.setKeyFields(keyInstance, keys.values().toArray());
-    dataStore.delete(keyInstance);
-  }
-
-  @Override
-  public void createData(EdmEntitySet entitySet, Object data)
-          throws ODataNotImplementedException, EdmException, ODataApplicationException {
-
-    DataStore<Object> dataStore = getDataStore(entitySet);
-    dataStore.create(data);
-  }
-
-  @Override
-  public void deleteRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
-          Map<String, Object> targetKeys)
-          throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
-  }
-
-  @Override
-  public void writeRelation(EdmEntitySet sourceEntitySet, Object sourceData, EdmEntitySet targetEntitySet,
-          Map<String, Object> targetKeys)
-          throws ODataNotImplementedException, ODataNotFoundException, EdmException, ODataApplicationException {
-    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
-  }
-
-
-  /**
-   * Returns corresponding DataStore for EdmEntitySet or if no data store is registered an
-   * ODataRuntimeException is thrown.
-   * Never returns NULL.
-   * 
-   * @param entitySet for which the corresponding DataStore is returned
-   * @return a DataStore object 
-   * @throws EdmException 
-   * @throws  ODataRuntimeException if no DataStore is found
-   */
-  private DataStore<Object> getDataStore(EdmEntitySet entitySet) throws EdmException {
-    final String name = entitySet.getEntityType().getName();
-    DataStore<Object> dataStore = dataStores.get(name);
-    if(dataStore == null) {
-      throw new ODataRuntimeException("No DataStore found for entity set '" + entitySet + "'.");
-    }
-    return dataStore;
-  }
-
-  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);
-    }
-  }
-
-  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/b7e7ee0d/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
deleted file mode 100644
index 5963131..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/AnnotationValueAccess.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ******************************************************************************/
-package org.apache.olingo.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;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
-
-/**
- *
- */
-public class AnnotationValueAccess implements ValueAccess {
-  private final AnnotationHelper annotationHelper = new AnnotationHelper();
-  
-  /**
-   * Retrieves the value of an EDM property for the given data object.
-   * @param data     the Java data object
-   * @param property the requested {@link EdmProperty}
-   * @return the requested property value
-   */
-  @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());
-    }
-    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
-  }
-
-  /**
-   * Sets the value of an EDM property for the given data object.
-   * @param data     the Java data object
-   * @param property the {@link EdmProperty}
-   * @param value    the new value of the property
-   */
-  @Override
-  public <T, V> void setPropertyValue(T data, final EdmProperty property, final V value) throws ODataException {
-    if(annotationHelper.isEdmAnnotated(data)) {
-      annotationHelper.setValueForProperty(data, property.getName(), value);
-    } else {
-      throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
-    }
-  }
-
-  /**
-   * Retrieves the Java type of an EDM property for the given data object.
-   * @param data     the Java data object
-   * @param property the requested {@link EdmProperty}
-   * @return the requested Java type
-   */
-  public <T> Class<?> getPropertyType(final T data, final EdmProperty property) throws ODataException {
-    if(annotationHelper.isEdmAnnotated(data)) {
-      Class<?> fieldType = annotationHelper.getFieldTypeForProperty(data, property.getName());
-      if(fieldType == null) {
-        throw new ODataException("No field type found for property " + property);
-      }
-      return fieldType;
-    }
-    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
-  }
-
-  /**
-   * Retrieves the value defined by a mapping object for the given data object.
-   * @param data     the Java data object
-   * @param mapping  the requested {@link EdmMapping}
-   * @return the requested value
-   */
-  public <T> Object getMappingValue(final T data, final EdmMapping mapping) throws ODataException {
-    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
-  }
-
-  /**
-   * Sets the value defined by a mapping object for the given data object.
-   * @param data     the Java data object
-   * @param mapping  the {@link EdmMapping}
-   * @param value    the new value
-   */
-  public <T, V> void setMappingValue(T data, final EdmMapping mapping, final V value) throws ODataException {
-    throw new ODataNotImplementedException(ODataNotImplementedException.COMMON);
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/BeanPropertyAccess.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/BeanPropertyAccess.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/BeanPropertyAccess.java
deleted file mode 100644
index 4b00c40..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/BeanPropertyAccess.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ******************************************************************************/
-package org.apache.olingo.odata2.core.annotation.ds;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-
-import org.apache.olingo.odata2.api.data.ValueAccess;
-import org.apache.olingo.odata2.api.edm.EdmException;
-import org.apache.olingo.odata2.api.edm.EdmMapping;
-import org.apache.olingo.odata2.api.edm.EdmProperty;
-import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
-import org.apache.olingo.odata2.api.exception.ODataException;
-import org.apache.olingo.odata2.api.exception.ODataHttpException;
-import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
-
-/**
- * Data access.
- */
-public class BeanPropertyAccess implements ValueAccess {
-
-  @Override
-  public <T> Object getPropertyValue(final T data, final EdmProperty property) throws ODataException {
-    return getValue(data, getGetterMethodName(property));
-  }
-
-  @Override
-  public <T, V> void setPropertyValue(T data, final EdmProperty property, final V value) throws ODataException {
-    final String methodName = getSetterMethodName(getGetterMethodName(property));
-    if (methodName != null) {
-      setValue(data, methodName, value);
-    }
-  }
-
-  @Override
-  public <T> Class<?> getPropertyType(final T data, final EdmProperty property) throws ODataException {
-    return getType(data, getGetterMethodName(property));
-  }
-
-  @Override
-  public <T> Object getMappingValue(final T data, final EdmMapping mapping) throws ODataException {
-    if (mapping != null && mapping.getMimeType() != null) {
-      return getValue(data, mapping.getMimeType());
-    }
-    return null;
-  }
-
-  @Override
-  public <T, V> void setMappingValue(T data, final EdmMapping mapping, final V value) throws ODataException {
-    if (mapping != null && mapping.getMimeType() != null) {
-      setValue(data, getSetterMethodName(mapping.getMimeType()), value);
-    }
-  }
-
-  private String getGetterMethodName(final EdmProperty property) throws EdmException {
-    final String prefix = isBooleanProperty(property) ? "is" : "get";
-    final String defaultMethodName = prefix + property.getName();
-    return property.getMapping() == null || property.getMapping().getInternalName() == null ?
-        defaultMethodName : property.getMapping().getInternalName();
-  }
-
-  private boolean isBooleanProperty(final EdmProperty property) throws EdmException {
-    return property.isSimple() 
-        && property.getType() == EdmSimpleTypeKind.Boolean.getEdmSimpleTypeInstance();
-  }
-
-  private String getSetterMethodName(final String getterMethodName) {
-    return getterMethodName.contains(".") ?
-        null : getterMethodName.replaceFirst("^is", "set").replaceFirst("^get", "set");
-  }
-
-  private <T> Object getValue(final T data, final String methodName) throws ODataNotFoundException {
-    Object dataObject = data;
-
-    for (final String method : methodName.split("\\.", -1)) {
-      if (dataObject != null) {
-        try {
-          dataObject = dataObject.getClass().getMethod(method).invoke(dataObject);
-        } catch (SecurityException e) {
-          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
-        } catch (NoSuchMethodException e) {
-          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
-        } catch (IllegalArgumentException e) {
-          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
-        } catch (IllegalAccessException e) {
-          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
-        } catch (InvocationTargetException e) {
-          throw new ODataNotFoundException(ODataHttpException.COMMON, e);
-        }
-      }
-    }
-
-    return dataObject;
-  }
-
-  private <T, V> void setValue(final T data, final String methodName, final V value)
-      throws ODataNotFoundException {
-    try {
-      boolean found = false;
-      for (final Method method : Arrays.asList(data.getClass().getMethods())) {
-        if (method.getName().equals(methodName)) {
-          found = true;
-          final Class<?> type = method.getParameterTypes()[0];
-          if (value == null) {
-            if (type.equals(byte.class) || type.equals(short.class) || type.equals(int.class)
-                || type.equals(long.class) || type.equals(char.class)) {
-              method.invoke(data, 0);
-            } else if (type.equals(float.class) || type.equals(double.class)) {
-              method.invoke(data, 0.0);
-            } else if (type.equals(boolean.class)) {
-              method.invoke(data, false);
-            } else {
-              method.invoke(data, value);
-            }
-          } else {
-            method.invoke(data, value);
-          }
-          break;
-        }
-      }
-      if (!found) {
-        throw new ODataNotFoundException(null);
-      }
-    } catch (SecurityException e) {
-      throw new ODataNotFoundException(null, e);
-    } catch (IllegalArgumentException e) {
-      throw new ODataNotFoundException(null, e);
-    } catch (IllegalAccessException e) {
-      throw new ODataNotFoundException(null, e);
-    } catch (InvocationTargetException e) {
-      throw new ODataNotFoundException(null, e);
-    }
-  }
-
-  private <T> Class<?> getType(final T data, final String methodName) throws ODataNotFoundException {
-    if (data == null) {
-      throw new ODataNotFoundException(ODataHttpException.COMMON);
-    }
-
-    Class<?> type = data.getClass();
-    for (final String method : methodName.split("\\.", -1)) {
-      try {
-        type = type.getMethod(method).getReturnType();
-        if (type.isPrimitive()) {
-          if (type == boolean.class) {
-            type = Boolean.class;
-          } else if (type == byte.class) {
-            type = Byte.class;
-          } else if (type == short.class) {
-            type = Short.class;
-          } else if (type == int.class) {
-            type = Integer.class;
-          } else if (type == long.class) {
-            type = Long.class;
-          } else if (type == float.class) {
-            type = Float.class;
-          } else if (type == double.class) {
-            type = Double.class;
-          }
-        }
-      } catch (final SecurityException e) {
-        throw new ODataNotFoundException(ODataHttpException.COMMON, e);
-      } catch (final NoSuchMethodException e) {
-        throw new ODataNotFoundException(ODataHttpException.COMMON, e);
-      }
-    }
-    return type;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/DataSourceHolder.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/DataSourceHolder.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/DataSourceHolder.java
deleted file mode 100644
index cb5502b..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/DataSourceHolder.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ******************************************************************************/
-package org.apache.olingo.odata2.core.annotation.ds;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityCreate;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDataSource;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDelete;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityRead;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntitySetRead;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityUpdate;
-import org.apache.olingo.odata2.api.uri.KeyPredicate;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
-
-/**
- *
- */
-public final class DataSourceHolder {
-
-  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
-  private static final Object[] EMPTY_ARRAY = new Object[0];
-  
-  private final String name;
-  private final Object dataSourceInstance;
-  private final Class<?> entityTypeClass;
-  private Method readMethod;
-  private Method createMethod;
-  private Method updateMethod;
-  private Method deleteMethod;
-  private Method readSetMethod;
-
-  public DataSourceHolder(Class<?> clz) {
-    EntityDataSource eds = clz.getAnnotation(EntityDataSource.class);
-    entityTypeClass = eds.entityType();
-    EdmEntityType entityType = entityTypeClass.getAnnotation(EdmEntityType.class);
-    if (entityType == null) {
-      throw new IllegalArgumentException("Missing EdmEntityType Annotation at class " + clz);
-    }
-
-    if (entityType.name().isEmpty()) {
-      name = ANNOTATION_HELPER.getCanonicalName(entityTypeClass);
-    } else {
-      name = entityType.name();
-    }
-    dataSourceInstance = createInstance(clz);
-    initMethods(clz);
-  }
-
-  private void initMethods(Class<?> clz) throws IllegalArgumentException, SecurityException {
-    Method[] methods = clz.getDeclaredMethods();
-    for (Method method : methods) {
-      EntityRead ec = method.getAnnotation(EntityRead.class);
-      if (ec != null) {
-        readMethod = method;
-      }
-      EntityCreate ep = method.getAnnotation(EntityCreate.class);
-      if (ep != null) {
-        createMethod = method;
-      }
-      EntityUpdate update = method.getAnnotation(EntityUpdate.class);
-      if (update != null) {
-        updateMethod = method;
-      }
-      EntityDelete delete = method.getAnnotation(EntityDelete.class);
-      if (delete != null) {
-        deleteMethod = method;
-      }
-      EntitySetRead readSet = method.getAnnotation(EntitySetRead.class);
-      if (readSet != null) {
-        readSetMethod = method;
-      }
-    }
-
-    validateMethods(clz);
-  }
-
-  private void validateMethods(Class<?> clz) throws IllegalArgumentException {
-    //
-    if (readMethod == null) {
-      throw new IllegalArgumentException("Missing " + EntityRead.class
-              + " annotation at " + EntityDataSource.class + " annotated class " + clz);
-    }
-    if (updateMethod == null) {
-      throw new IllegalArgumentException("Missing " + EntityUpdate.class
-              + " annotation at " + EntityDataSource.class + " annotated class " + clz);
-    }
-    if (createMethod == null) {
-      throw new IllegalArgumentException("Missing " + EntityCreate.class
-              + " annotation at " + EntityDataSource.class + " annotated class " + clz);
-    }
-    
-    if(readSetMethod != null) {
-      if(!Collection.class.isAssignableFrom(readSetMethod.getReturnType())) {
-        throw new IllegalArgumentException("Read set method must have a return type which is assignable to " 
-            + Collection.class + " but return type for annotated method " + readSetMethod + " is " 
-            + readSetMethod.getReturnType());
-      }
-    }
-  }
-
-  public Object readEntity(Object[] keyValues) {
-    if (readMethod.getParameterTypes().length != keyValues.length) {
-      throw new IllegalStateException("Wrong amount of key properties. Expected read keys = "
-              + Arrays.toString(readMethod.getParameterTypes()) + " given key predicates = " 
-              + Arrays.toString(keyValues));
-    }
-
-    return invoke(readMethod, keyValues);
-  }
-
-  public Object readEntity(List<KeyPredicate> keys) {
-    Object[] parameterKeys = mapParameterKeys(readMethod, keys);
-    return invoke(readMethod, parameterKeys);
-  }
-
-  private Object[] mapParameterKeys(Method method, List<KeyPredicate> keys) throws IllegalStateException {
-    if(method == null) {
-      return EMPTY_ARRAY;
-    }
-    Class<?>[] pTypes = method.getParameterTypes();
-    if (pTypes.length != keys.size()) {
-      throw new IllegalStateException("Wrong amount of key properties. Expected read keys = "
-              + Arrays.toString(pTypes) + " given key predicates = " + keys);
-    }
-    Object[] parameterKeys = new Object[pTypes.length];
-    int i = 0;
-    for (KeyPredicate keyPredicate : keys) {
-      if (matches(pTypes[i], keyPredicate)) {
-        parameterKeys[i] = keyPredicate.getLiteral();
-      }
-      i++;
-    }
-    return parameterKeys;
-  }
-
-  public Object createEntity(Object key) {
-    return invoke(createMethod, new Object[]{key});
-  }
-
-  public Object updateEntity(Object key) {
-    return invoke(updateMethod, new Object[]{key});
-  }
-
-  public Object deleteEntity(List<KeyPredicate> keys) {
-    Object[] parameterKeys = mapParameterKeys(deleteMethod, keys);
-    return invoke(deleteMethod, parameterKeys);
-  }
-
-  public Collection<?> readEntitySet() {
-    return (Collection<?>) invoke(readSetMethod, new Object[0]);
-  }
-
-  private Object invoke(Method m, Object[] objs) {
-    try {
-      return m.invoke(dataSourceInstance, objs);
-    } catch (Exception ex) {
-      return null;
-    }
-  }
-
-  public Object createEntityInstance() {
-    return createInstance(this.entityTypeClass);
-  }
-
-  private static Object createInstance(Class<?> clz) {
-    try {
-      return clz.newInstance();
-    } catch (Exception ex) {
-      return null;
-    }
-  }
-
-  public String getEntityName() {
-    return this.name;
-  }
-
-  public Class<?> getEntityTypeClass() {
-    return entityTypeClass;
-  }
-
-  @Override
-  public String toString() {
-    return "DataSourceHolder{" + "name=" + name + ", dataSourceInstance=" + dataSourceInstance + 
-            ", entityTypeClass=" + entityTypeClass + ", consumerMethod=" + readMethod + 
-            ", createMethod=" + createMethod + ", updateMethod=" + updateMethod + '}';
-  }
-
-  private boolean matches(Class<?> aClass, KeyPredicate type) {
-    return true;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/DataStore.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/DataStore.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/DataStore.java
deleted file mode 100644
index 77eb47d..0000000
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/ds/DataStore.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- ******************************************************************************/
-package org.apache.olingo.odata2.core.annotation.ds;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityCreate;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDelete;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityRead;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntitySetRead;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityUpdate;
-import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-/**
- *
- */
-public class DataStore<T> {
-
-  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
-  private final List<T> dataStore;
-  private final Class<T> dataTypeClass;
-
-  private int idCounter = 1;
-  
-  private static class InMemoryDataStore {
-    private static final Map<Class<?>, DataStore<?>> c2ds = new HashMap<Class<?>, DataStore<?>>();
-    @SuppressWarnings("unchecked")
-    static DataStore<?> getInstance(Class<?> clz) {
-      DataStore<?> ds = c2ds.get(clz);
-      if(ds == null) {
-        ds = new DataStore<Object>((Class<Object>) clz);
-        c2ds.put(clz, ds);
-      }
-      return ds;
-    }
-  }
-  
-  @SuppressWarnings("unchecked")
-  public static <T> DataStore<T> createInMemory(Class<T> clazz) {
-    return (DataStore<T>) InMemoryDataStore.getInstance(clazz);
-  }
-  
-  private DataStore(List<T> wrapStore, Class<T> clz) {
-    dataStore = wrapStore;
-    dataTypeClass = clz;
-  }
-
-  private DataStore(Class<T> clz) {
-    this(new ArrayList<T>(), clz);
-  }
-  
-  public Class<T> getDataTypeClass() {
-    return dataTypeClass;
-  }
-  
-  public T createInstance() {
-    try {
-      return dataTypeClass.newInstance();
-    } catch (InstantiationException e) {
-      throw new ODataRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
-    } catch (IllegalAccessException e) {
-      throw new ODataRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
-    }
-  }
-  
-  @EntityRead
-  public T read(T obj) {
-    List<Object> objKeys = getKeys(obj);
-    for (T stored : dataStore) {
-      if (objKeys.equals(getKeys(stored))) {
-        return stored;
-      }
-    }
-    return null;
-  }
-
-  @EntitySetRead
-  public Collection<T> read() {
-    return Collections.unmodifiableCollection(dataStore);
-  }
-
-  @EntityCreate
-  public T create(T object) {
-    createKeys(object);
-    dataStore.add(object);
-    return object;
-  }
-
-  @EntityUpdate
-  public T update(T object) {
-    T stored = read(object);
-    dataStore.remove(stored);
-    dataStore.add(object);
-    return object;
-  }
-
-  @EntityDelete
-  public T delete(T object) {
-    T stored = read(object);
-    if(stored != null) {    
-      dataStore.remove(stored);
-    }
-    return stored;
-  }
-  
-  private List<Object> getKeys(T object) {
-    Map<String, Object> keys = ANNOTATION_HELPER.getValueForAnnotatedFields(object, EdmKey.class);
-    
-    // XXX: list should be in a defined order -> better to create an 'Key' object which is comparable 
-    List<Object> keyList = new ArrayList(keys.values());
-    return keyList;
-  }
-  
-  private T createKeys(T object) {
-    List<Field> fields = ANNOTATION_HELPER.getAnnotatedFields(object, EdmKey.class);
-    Map<String, Object> fieldName2KeyValue = new HashMap<String, Object>();
-    
-    for (Field field : fields) {
-      Object key = createKey(field);
-      fieldName2KeyValue.put(ANNOTATION_HELPER.getCanonicalName(field), key);
-    }
-    
-    ANNOTATION_HELPER.setValuesToAnnotatedFields(fieldName2KeyValue, object, EdmKey.class);
-    
-    return object;
-  }
-
-  private Object createKey(Field field) {
-    Class<?> type = field.getType();
-    
-    if(type == String.class) {
-      return String.valueOf(idCounter++);
-    } else if(type == Integer.class || type == int.class) {
-      return Integer.valueOf(idCounter++);
-    } else if(type == Long.class || type == long.class) {
-      return Long.valueOf(idCounter++);
-    }
-    
-    throw new UnsupportedOperationException("Automated key generation for type '" + type
-            + "' is not supported (caused on field '" + field + "').");
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/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 b7aa89b..75a92a2 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
@@ -446,7 +446,7 @@ public class AnnotationEdmProvider extends EdmProvider {
 
     private Property createProperty(EdmProperty ep, Field field, String defaultNamespace) {
       if(isAnnotatedEntity(field.getType())) {
-        return createComplexProperty(ep, field, defaultNamespace);
+        return createComplexProperty(field, defaultNamespace);
       } else {
         return createSimpleProperty(ep, field);
       }
@@ -455,10 +455,7 @@ public class AnnotationEdmProvider extends EdmProvider {
 
     private Property createSimpleProperty(EdmProperty ep, Field field) {
       SimpleProperty sp = new SimpleProperty();
-      String entityName = ep.name();
-      if (entityName.isEmpty()) {
-        entityName = getCanonicalName(field);
-      }
+      String entityName = ANNOTATION_HELPER.getPropertyName(field);
       sp.setName(entityName);
       //
       EdmSimpleTypeKind type = ep.type();
@@ -470,13 +467,10 @@ public class AnnotationEdmProvider extends EdmProvider {
       return sp;
     }
 
-    private Property createComplexProperty(EdmProperty ep, Field field, String defaultNamespace) {
+    private Property createComplexProperty(Field field, String defaultNamespace) {
       ComplexProperty cp = new ComplexProperty();
       // settings from property
-      String entityName = ep.name();
-      if (entityName.isEmpty()) {
-        entityName = getCanonicalName(field);
-      }
+      String entityName = ANNOTATION_HELPER.getPropertyName(field);
       cp.setName(entityName);
       
       // settings from related complex entity
@@ -492,10 +486,7 @@ public class AnnotationEdmProvider extends EdmProvider {
 
     private NavigationProperty createNavigationProperty(String namespace, EdmNavigationProperty enp, Field field) {
       NavigationProperty navProp = new NavigationProperty();
-      String entityName = enp.name();
-      if (entityName.isEmpty()) {
-        entityName = getCanonicalName(field);
-      }
+      String entityName = ANNOTATION_HELPER.getPropertyName(field);
       navProp.setName(entityName);
       //
       NavigationEnd from = enp.from();