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/11/15 12:58:52 UTC

[1/2] Added support for multiple 'EdmKey' annotations

Updated Branches:
  refs/heads/PocEdmAnnotationsExtension a8ff9e211 -> b7e7ee0df


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/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 d43f8c9..cca0b5e 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
@@ -78,14 +78,57 @@ public class AnnotationHelper {
     }
   }
 
+  /**
+   * Get the set property name from an EdmProperty or EdmNavigationProperty annotation.
+   * 
+   * @param field
+   * @return 
+   */
+  public String getPropertyNameFromAnnotation(Field field) {
+    EdmProperty property = field.getAnnotation(EdmProperty.class);
+    if(property == null) {
+      EdmNavigationProperty navProperty = field.getAnnotation(EdmNavigationProperty.class);
+      if(navProperty == null) {
+        throw new EdmAnnotationException("Given field '" + field
+                + "' has no EdmProperty or EdmNavigationProperty annotation.");
+      }
+      return navProperty.name();
+    }
+    return property.name();
+  }
+
+  public String getPropertyName(Field field) {
+      String propertyName = getPropertyNameFromAnnotation(field);
+      if (propertyName.isEmpty()) {
+        propertyName = getCanonicalName(field);
+      }
+      return propertyName;
+  }
+
   public static final class ODataAnnotationException extends ODataException {
 
     public ODataAnnotationException(String message) {
       super(message);
     }
   }
-  
-  public <T> T setKeyFields(T instance, Object[] keyValues) {
+
+  public <T> T setKeyFields(T instance, Map<String, Object> keys) {
+    List<Field> fields = getAnnotatedFields(instance, EdmKey.class);
+    if (fields.size() != keys.size()) {
+      throw new IllegalStateException("Wrong amount of key properties. Expected read keys = "
+              + fields + " given key predicates = " + keys);
+    }
+    
+    for (Field field : fields) {
+      String propertyName = getPropertyName(field);
+      Object keyValue = keys.get(propertyName);
+      setValueForProperty(instance, propertyName, keyValue);
+    }
+
+    return instance;
+  }
+
+  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 = "
@@ -370,7 +413,8 @@ public class AnnotationHelper {
       return type.getEdmSimpleTypeInstance().valueOfString(propertyValue,
               EdmLiteralKind.DEFAULT, null, fieldClass);
     } catch (EdmSimpleTypeException ex) {
-      throw new ODataRuntimeException(ex);
+      throw new ODataRuntimeException("Conversion failed for string property with error: " 
+              + ex.getMessage(), ex);
     }
   }
 
@@ -406,4 +450,11 @@ public class AnnotationHelper {
     }
     return content.substring(0, 1).toUpperCase(Locale.ENGLISH) + content.substring(1);
   }
+
+  
+  private static class EdmAnnotationException extends RuntimeException {
+    public EdmAnnotationException(String message) {
+      super(message);
+    }
+  }
 }

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/processor/AnnotationProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java
index 23fc743..b1b8730 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java
@@ -44,7 +44,7 @@ import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
 import org.apache.olingo.odata2.api.uri.info.GetMediaResourceUriInfo;
 import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
 import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
-import org.apache.olingo.odata2.core.annotation.ds.DataSourceHolder;
+import org.apache.olingo.odata2.core.annotation.data.DataSourceHolder;
 import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
 import org.apache.olingo.odata2.core.annotation.edm.ClassHelper;
 import org.apache.olingo.odata2.core.annotation.processor.json.EdmAnnotationSerializer;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
new file mode 100644
index 0000000..0aaf309
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/data/AnnotationsInMemoryDsTest.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed 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.HashMap;
+import java.util.Map;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.EntityType;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.core.annotation.edm.AnnotationEdmProvider;
+import org.apache.olingo.odata2.core.annotation.model.Building;
+import org.apache.olingo.odata2.core.annotation.model.ModelSharedConstants;
+import org.apache.olingo.odata2.core.annotation.model.Photo;
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ *
+ */
+public class AnnotationsInMemoryDsTest {
+  
+  private final AnnotationInMemoryDs datasource;
+  private AnnotationEdmProvider edmProvider;
+  private static final String DEFAULT_CONTAINER = ModelSharedConstants.CONTAINER_1;
+  private static final String DEFAULT_NAMESPACE = ModelSharedConstants.NAMESPACE_1;
+
+  public AnnotationsInMemoryDsTest() {
+    datasource = new AnnotationInMemoryDs(Building.class.getPackage().getName());
+    edmProvider = new AnnotationEdmProvider(Building.class.getPackage().getName());
+  }
+
+
+  @Test(expected = ODataApplicationException.class)
+  public void invalidEntity() throws Exception {
+    EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Building");
+    
+    datasource.createData(edmEntitySet, this);
+  }
+
+  @Test
+  public void createSimpleEntity() throws Exception {
+    EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Building");
+    
+    Building building = new Building();
+    building.setName("Common Building");
+    datasource.createData(edmEntitySet, building);
+    
+    Map<String, Object> keys = new HashMap<String, Object>();
+    keys.put("Id", "1");
+    
+    Building read = (Building) datasource.readData(edmEntitySet, keys);
+    Assert.assertEquals("Common Building", read.getName());
+  }
+
+  @Test
+  public void createEntityTwoKeys() throws Exception {
+    EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Photo");
+    
+    Photo photo = new Photo();
+    photo.setName("BigPicture");
+    photo.setType("PNG");
+    photo.setImageUri("https://localhost/image.png");
+    photo.setImageType("image/png");
+    datasource.createData(edmEntitySet, photo);
+    
+    Map<String, Object> keys = new HashMap<String, Object>();
+//    keys.put("ImageFormat", "PNG");
+//    keys.put("Name", "BigPicture");
+    keys.put("Name", "1");
+    keys.put("ImageFormat", "2");
+    
+    Photo read = (Photo) datasource.readData(edmEntitySet, keys);
+//    Assert.assertEquals("BigPicture", read.getName());
+    Assert.assertEquals("1", read.getName());
+    Assert.assertEquals("2", read.getType());
+    Assert.assertEquals("image/png", read.getImageType());
+    Assert.assertEquals("https://localhost/image.png", read.getImageUri());
+  }
+
+  @Test
+//  @Ignore("Rethink update method")
+  public void createAndUpdateEntityTwoKeys() throws Exception {
+    EdmEntitySet edmEntitySet = createMockedEdmEntitySet("Photo");
+    
+    Photo photo = new Photo();
+    final String nameKeyValue = "BigPicture";
+    final String typeKeyValue = "PNG";
+    photo.setName(nameKeyValue);
+    photo.setType(typeKeyValue);
+    photo.setImageUri("https://localhost/image.png");
+    photo.setImageType("image/png");
+    datasource.createData(edmEntitySet, photo);
+    
+    Map<String, Object> keys = new HashMap<String, Object>();
+    keys.put("Name", "1");
+    keys.put("ImageFormat", "2");
+    
+    Photo read = (Photo) datasource.readData(edmEntitySet, keys);
+    Assert.assertEquals("1", read.getName());
+    Assert.assertEquals("2", read.getType());
+    Assert.assertEquals("image/png", read.getImageType());
+    Assert.assertEquals("https://localhost/image.png", read.getImageUri());
+    
+
+    // update
+    Photo updatedPhoto = new Photo();
+//    updatedPhoto.setName(nameKeyValue);
+//    updatedPhoto.setType(typeKeyValue);
+    updatedPhoto.setName("1");
+    updatedPhoto.setType("2");
+    updatedPhoto.setImageUri("https://localhost/image.jpg");
+    updatedPhoto.setImageType("image/jpg");
+    datasource.updateData(edmEntitySet, updatedPhoto);
+    
+    Map<String, Object> updatedKeys = new HashMap<String, Object>();
+//    updatedKeys.put("Name", nameKeyValue);
+//    updatedKeys.put("ImageFormat", typeKeyValue);
+    updatedKeys.put("Name", "1");
+    updatedKeys.put("ImageFormat", "2");
+    
+    Photo readUpdated = (Photo) datasource.readData(edmEntitySet, updatedKeys);
+    Assert.assertEquals("1", readUpdated.getName());
+    Assert.assertEquals("2", readUpdated.getType());
+    Assert.assertEquals("image/jpg", readUpdated.getImageType());
+    Assert.assertEquals("https://localhost/image.jpg", readUpdated.getImageUri());
+  }
+
+  private EdmEntitySet createMockedEdmEntitySet(String entitySetName) throws ODataException {
+//    EntitySet entitySet = edmProvider.getEntitySet(DEFAULT_CONTAINER, entitySetName);
+    EntityType entityType = edmProvider.getEntityType(new FullQualifiedName(DEFAULT_NAMESPACE, entitySetName));
+    
+    EdmEntitySet edmEntitySet = Mockito.mock(EdmEntitySet.class);
+    EdmEntityType edmEntityType = Mockito.mock(EdmEntityType.class);
+    Mockito.when(edmEntitySet.getEntityType()).thenReturn(edmEntityType);
+    Mockito.when(edmEntityType.getName()).thenReturn(entityType.getName());
+    
+    return edmEntitySet;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
index 4a875a2..4d1a6b7 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProviderTest.java
@@ -36,6 +36,7 @@ import org.apache.olingo.odata2.api.edm.provider.EntityContainerInfo;
 import org.apache.olingo.odata2.api.edm.provider.EntitySet;
 import org.apache.olingo.odata2.api.edm.provider.EntityType;
 import org.apache.olingo.odata2.api.edm.provider.FunctionImport;
+import org.apache.olingo.odata2.api.edm.provider.Key;
 import org.apache.olingo.odata2.api.edm.provider.NavigationProperty;
 import org.apache.olingo.odata2.api.edm.provider.Property;
 import org.apache.olingo.odata2.api.edm.provider.PropertyRef;
@@ -50,11 +51,11 @@ import org.apache.olingo.odata2.core.annotation.model.Photo;
 import org.apache.olingo.odata2.core.annotation.model.RefBase;
 import org.apache.olingo.odata2.core.annotation.model.Room;
 import org.apache.olingo.odata2.core.annotation.model.Team;
+import static org.junit.Assert.assertFalse;
 import org.junit.Test;
 
 /**
  *
- * @author d046871
  */
 public class AnnotationEdmProviderTest {
 
@@ -148,7 +149,7 @@ public class AnnotationEdmProviderTest {
     EntityContainer container = containers.get(0);
     assertEquals(ModelSharedConstants.CONTAINER_1, container.getName());
     final List<EntitySet> entitySets = container.getEntitySets();
-    assertEquals(5, entitySets.size());
+    assertEquals(6, entitySets.size());
     
     List<Association> associations = schema.getAssociations();
     assertEquals(4, associations.size());
@@ -257,6 +258,33 @@ public class AnnotationEdmProviderTest {
   }
 
   @Test
+  public void entityTypePhotoWithTwoKeyProperties() throws Exception {
+    // validate team
+    EntityType photo = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Photo"));
+    assertEquals("Photo", photo.getName());
+    final List<Property> properties = photo.getProperties();
+    assertEquals(5, properties.size());
+    assertTrue(containsProperty(properties, "Name"));
+    assertTrue(containsProperty(properties, "ImageFormat"));
+    assertTrue(containsProperty(properties, "MimeType"));
+    assertTrue(containsProperty(properties, "ImageUrl"));
+    assertTrue(containsProperty(properties, "Image"));
+    assertFalse(photo.isAbstract());
+    assertTrue(photo.isHasStream());
+
+    Key photoKey = photo.getKey();
+    List<PropertyRef> keyReferences = photoKey.getKeys();
+    assertEquals(2, keyReferences.size());
+    PropertyRef name = getPropertyRef(keyReferences, "Name");
+    assertEquals("Name", name.getName());
+    PropertyRef imageFormat = getPropertyRef(keyReferences, "ImageFormat");
+    assertEquals("ImageFormat", imageFormat.getName());
+    
+//    assertEquals(0, photo.getNavigationProperties().size());
+    assertNull(photo.getNavigationProperties());
+  }
+
+  @Test
   public void entityTypeAbstractBaseType() throws Exception {
     // validate employee
     EntityType baseType = aep.getEntityType(new FullQualifiedName(ModelSharedConstants.NAMESPACE_1, "Base"));
@@ -331,4 +359,26 @@ public class AnnotationEdmProviderTest {
           String relationship, String fromRole, String toRole) {
     validateNavProperty(navigationProperty, null, relationship, fromRole, toRole);
   }
+  
+  private boolean containsProperty(List<Property> properties, String propertyName) {
+    return getProperty(properties, propertyName) != null;
+  }
+
+  private Property getProperty(List<Property> properties, String name) {
+    for (Property property : properties) {
+      if(name.equals(property.getName())) {
+        return property;
+      }
+    }
+    return null;
+  }
+  
+  private PropertyRef getPropertyRef(List<PropertyRef> properties, String name) {
+    for (PropertyRef property : properties) {
+      if(name.equals(property.getName())) {
+        return property;
+      }
+    }
+    return null;
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
index 2abf4e3..f1a3fa9 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Building.java
@@ -39,7 +39,7 @@ import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
 public class Building {
   @EdmKey
   @EdmProperty(type = EdmSimpleTypeKind.String)
-  private int id;
+  private String id;
   @EdmProperty
   private String name;
   private byte[] image;
@@ -47,16 +47,8 @@ public class Building {
           to = @NavigationEnd(role = "r_Room", entitySet=Room.class, multiplicity = EdmMultiplicity.MANY))
   private List<Room> rooms = new ArrayList<Room>();
 
-  public Building() {
-  }
-
-  public Building(final int id, final String name) {
-    this.id = id;
-    setName(name);
-  }
-
   public String getId() {
-    return Integer.toString(id);
+    return id;
   }
 
   public void setName(final String name) {
@@ -85,7 +77,10 @@ public class Building {
 
   @Override
   public int hashCode() {
-    return id;
+    if(id == null) {
+      return 0;
+    }
+    return id.hashCode();
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
index 6c89654..52cb2cc 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/Photo.java
@@ -19,31 +19,38 @@
 package org.apache.olingo.odata2.core.annotation.model;
 
 import java.util.Arrays;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+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.EdmMediaResourceContent;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceSource;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.core.annotation.model.ModelSharedConstants;
+import org.apache.olingo.odata2.core.annotation.model.ResourceHelper;
 
 /**
  *  
  */
+@EdmEntityType(name = "Photo", namespace = ModelSharedConstants.NAMESPACE_1)
+@EdmEntitySet(name = "Photos")
 public class Photo {
-  private static final String RESOURCE = "/male_1_WinterW.jpg";
-
-  private final int id;
+  @EdmProperty
+  @EdmKey
   private String name;
-  private String type = "image/jpeg";
-  private String imageUrl = "http://localhost" + RESOURCE;
-  private byte[] image = new byte[0];
-  private String imageType = type;
-  private byte[] binaryData;
-  private String content;
-
-  public Photo(final int id, final String name, final String type) {
-    this.id = id;
-    setName(name);
-    setType(type);
-  }
-
-  public int getId() {
-    return id;
-  }
+  @EdmProperty(name = "ImageFormat")
+  @EdmKey
+  private String type;
+  @EdmProperty
+  @EdmMediaResourceMimeType
+  private String mimeType;
+  @EdmProperty
+  @EdmMediaResourceSource
+  private String imageUrl = "http://localhost/someResource.png";
+  @EdmProperty(type = EdmSimpleTypeKind.Binary)
+  @EdmMediaResourceContent
+  private byte[] image = ResourceHelper.generateImage();
 
   public String getName() {
     return name;
@@ -78,53 +85,45 @@ public class Photo {
   }
 
   public String getImageType() {
-    return imageType;
+    return mimeType;
   }
 
   public void setImageType(final String imageType) {
-    this.imageType = imageType;
-  }
-
-  public byte[] getBinaryData() {
-    if (binaryData == null) {
-      return null;
-    } else {
-      return binaryData.clone();
-    }
-  }
-
-  public void setBinaryData(final byte[] binaryData) {
-    this.binaryData = binaryData;
-  }
-
-  public void setContent(final String content) {
-    this.content = content;
-  }
-
-  public String getContent() {
-    return content;
+    this.mimeType = imageType;
   }
 
   @Override
   public int hashCode() {
-    return id;
+    int hash = 5;
+    hash = 83 * hash + (this.name != null ? this.name.hashCode() : 0);
+    hash = 83 * hash + (this.type != null ? this.type.hashCode() : 0);
+    return hash;
   }
 
   @Override
-  public boolean equals(final Object obj) {
-    return this == obj
-        || obj != null && getClass() == obj.getClass() && id == ((Photo) obj).id;
+  public boolean equals(Object obj) {
+    if (obj == null) {
+      return false;
+    }
+    if (getClass() != obj.getClass()) {
+      return false;
+    }
+    final Photo other = (Photo) obj;
+    if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
+      return false;
+    }
+    if ((this.type == null) ? (other.type != null) : !this.type.equals(other.type)) {
+      return false;
+    }
+    return true;
   }
-
+  
   @Override
   public String toString() {
-    return "{\"Id\":" + id + ","
-        + "\"Name\":\"" + name + "\","
+    return "{\"Name\":\"" + name + "\","
         + "\"Type\":\"" + type + "\","
         + "\"ImageUrl\":\"" + imageUrl + "\","
         + "\"Image\":\"" + Arrays.toString(image) + "\","
-        + "\"ImageType\":\"" + imageType + "\","
-        + "\"Content:\"" + content + "\","
-        + "\"BinaryData\":\"" + Arrays.toString(binaryData) + "\"}";
+        + "\"MimeType\":\"" + mimeType + "\"";
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java
new file mode 100644
index 0000000..73d1218
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/test/java/org/apache/olingo/odata2/core/annotation/model/ResourceHelper.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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.model;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.WritableRaster;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.imageio.ImageIO;
+
+/**
+ *
+ */
+public class ResourceHelper {
+
+  public enum Format {BMP, JPEG, PNG, GIF};
+  
+  public static byte[] generateImage() {
+    return generateImage(Format.PNG);
+  }
+  
+  public static byte[] generateImage(Format format) {
+    try {
+      int width = 320;
+      int height = 320;
+      BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
+      WritableRaster raster = image.getRaster();
+      
+      int mod = format.ordinal() + 2;
+      for (int h = 0; h < height; h++) {
+        for (int w = 0; w < width; w++) {
+          if (((h / 32) + (w / 32)) % mod == 0) {
+            raster.setSample(w, h, 0, 0);
+          } else {
+            raster.setSample(w, h, 0, 1);
+          }
+        }
+      }
+      
+      ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
+      ImageIO.write(image, format.name(), out);
+      return out.toByteArray();
+    } catch (IOException ex) {
+      return new byte[0];
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
index 3623b2b..eafee7b 100644
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/java/org/apache/olingo/odata2/ref/annotation/model/Photo.java
@@ -34,9 +34,10 @@ import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
 @EdmEntityType(name = "Photo", namespace = ModelSharedConstants.NAMESPACE_1)
 @EdmEntitySet(name = "Photos")
 public class Photo {
-  @EdmProperty
   @EdmKey
+  @EdmProperty
   private String name;
+  @EdmKey
   @EdmProperty
   private String type;
   @EdmProperty

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/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 9dcac65..5210466 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
@@ -14,8 +14,8 @@
  */
 package org.apache.olingo.odata2.ref.annotation.processor;
 
-import org.apache.olingo.odata2.core.annotation.ds.AnnotationValueAccess;
-import org.apache.olingo.odata2.core.annotation.ds.AnnotationInMemoryDs;
+import org.apache.olingo.odata2.core.annotation.data.AnnotationValueAccess;
+import org.apache.olingo.odata2.core.annotation.data.AnnotationInMemoryDs;
 import org.apache.olingo.odata2.api.ODataCallback;
 import org.apache.olingo.odata2.api.ODataDebugCallback;
 import org.apache.olingo.odata2.api.ODataService;
@@ -28,13 +28,12 @@ import org.apache.olingo.odata2.api.processor.ODataContext;
 import org.apache.olingo.odata2.api.processor.ODataErrorCallback;
 import org.apache.olingo.odata2.api.processor.ODataErrorContext;
 import org.apache.olingo.odata2.api.processor.ODataResponse;
-import org.apache.olingo.odata2.core.annotation.ds.DataStore;
+import org.apache.olingo.odata2.core.annotation.data.DataStore;
 import org.apache.olingo.odata2.core.annotation.edm.AnnotationEdmProvider;
 import org.apache.olingo.odata2.core.annotation.processor.ListsProcessor;
 import org.apache.olingo.odata2.ref.annotation.model.Building;
 import org.apache.olingo.odata2.ref.annotation.model.Photo;
 import org.apache.olingo.odata2.ref.annotation.model.ResourceHelper;
-import org.apache.olingo.odata2.ref.annotation.model.ResourceHelper;
 import org.apache.olingo.odata2.ref.annotation.model.Room;
 import org.apache.olingo.odata2.ref.annotation.model.Team;
 import org.slf4j.Logger;
@@ -73,8 +72,6 @@ public class AnnotationPocServiceFactory extends ODataServiceFactory {
             ? new ScenarioDebugCallback() : super.getCallback(callbackInterface));
   }
 
-  
-  
   /*
   * Helper classes and methods
   */
@@ -105,7 +102,7 @@ public class AnnotationPocServiceFactory extends ODataServiceFactory {
 
   }
 
-  private void initializeSampleData(AnnotationInMemoryDs dataSource) {
+  private void initializeSampleData(AnnotationInMemoryDs dataSource) throws ODataApplicationException {
     DataStore<Team> teamDs = dataSource.getDataStore(Team.class);
     teamDs.create(createTeam("Team Alpha", true));
     teamDs.create(createTeam("Team Beta", false));

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp b/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp
index 3ffc551..dffa84d 100644
--- a/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp
+++ b/odata2-edm-annotation/edm-annotation-webref/src/main/webapp/index.jsp
@@ -77,11 +77,11 @@ th, td { border: 1px solid; padding: 20px; }
 						target="_blank">Employees('1')</a></li>
 					<li><a href="ReferenceScenario.svc/Managers('1')"
 						target="_blank">Managers('1')</a></li>
-					<li><a href="ReferenceScenario.svc/Buildings('1')"
-						target="_blank">Buildings('1')</a></li>
+					<li><a href="ReferenceScenario.svc/Buildings(1)"
+						target="_blank">Buildings(1)</a></li>
 					<li><a href="ReferenceScenario.svc/Rooms('1')" target="_blank">Rooms('1')</a></li>
- 					<li><a href="ReferenceScenario.svc/Container2.Photos(Id=4,Type='foo')"
-                           target="_blank">Container2.Photos(Id=4,Type='foo')</a></li>
+ 					<li><a href="ReferenceScenario.svc/Photos(Name='1',Type='2')"
+                           target="_blank">Container2.Photos(Name='1',Type='2')</a></li>
 				</ul>
 			</td>
 			<td valign="top">

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/AbstractRefTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/AbstractRefTest.java b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/AbstractRefTest.java
index e9e2153..de5f99e 100644
--- a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/AbstractRefTest.java
+++ b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/AbstractRefTest.java
@@ -39,7 +39,7 @@ import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
 import org.apache.olingo.odata2.api.commons.ODataHttpMethod;
 import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
 import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
-import org.apache.olingo.odata2.core.annotation.ds.BeanPropertyAccess;
+import org.apache.olingo.odata2.core.annotation.data.BeanPropertyAccess;
 import org.apache.olingo.odata2.core.annotation.processor.ListsProcessor;
 import org.apache.olingo.odata2.core.processor.ODataSingleProcessorService;
 import org.apache.olingo.odata2.ref.edm.ScenarioEdmProvider;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/contentnegotiation/AbstractContentNegotiationTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/contentnegotiation/AbstractContentNegotiationTest.java b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/contentnegotiation/AbstractContentNegotiationTest.java
index 265fc28..688532d 100644
--- a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/contentnegotiation/AbstractContentNegotiationTest.java
+++ b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/contentnegotiation/AbstractContentNegotiationTest.java
@@ -49,7 +49,7 @@ import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
 import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
 import org.apache.olingo.odata2.api.exception.ODataException;
 import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
-import org.apache.olingo.odata2.core.annotation.ds.BeanPropertyAccess;
+import org.apache.olingo.odata2.core.annotation.data.BeanPropertyAccess;
 import org.apache.olingo.odata2.core.annotation.processor.ListsProcessor;
 import org.apache.olingo.odata2.core.commons.ContentType;
 import org.apache.olingo.odata2.core.processor.ODataSingleProcessorService;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioServiceFactory.java b/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioServiceFactory.java
index 49cd8b2..08d6e16 100644
--- a/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioServiceFactory.java
+++ b/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioServiceFactory.java
@@ -24,7 +24,7 @@ import org.apache.olingo.odata2.api.ODataService;
 import org.apache.olingo.odata2.api.ODataServiceFactory;
 import org.apache.olingo.odata2.api.exception.ODataException;
 import org.apache.olingo.odata2.api.processor.ODataContext;
-import org.apache.olingo.odata2.core.annotation.ds.BeanPropertyAccess;
+import org.apache.olingo.odata2.core.annotation.data.BeanPropertyAccess;
 import org.apache.olingo.odata2.core.annotation.processor.ListsProcessor;
 import org.apache.olingo.odata2.ref.edm.ScenarioEdmProvider;
 import org.apache.olingo.odata2.ref.model.DataContainer;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-lib/odata-ref/src/test/java/org/apache/olingo/odata2/ref/read/EntitySetTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-ref/src/test/java/org/apache/olingo/odata2/ref/read/EntitySetTest.java b/odata2-lib/odata-ref/src/test/java/org/apache/olingo/odata2/ref/read/EntitySetTest.java
index 53fd6ef..d07473d 100644
--- a/odata2-lib/odata-ref/src/test/java/org/apache/olingo/odata2/ref/read/EntitySetTest.java
+++ b/odata2-lib/odata-ref/src/test/java/org/apache/olingo/odata2/ref/read/EntitySetTest.java
@@ -38,7 +38,7 @@ import org.apache.olingo.odata2.api.processor.ODataContext;
 import org.apache.olingo.odata2.api.processor.ODataResponse;
 import org.apache.olingo.odata2.api.uri.PathInfo;
 import org.apache.olingo.odata2.api.uri.UriInfo;
-import org.apache.olingo.odata2.core.annotation.ds.BeanPropertyAccess;
+import org.apache.olingo.odata2.core.annotation.data.BeanPropertyAccess;
 import org.apache.olingo.odata2.core.annotation.processor.ListsProcessor;
 import org.apache.olingo.odata2.core.commons.ContentType;
 import org.apache.olingo.odata2.ref.model.DataContainer;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/b7e7ee0d/odata2-lib/odata-ref/src/test/java/org/apache/olingo/odata2/ref/read/EntityTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-ref/src/test/java/org/apache/olingo/odata2/ref/read/EntityTest.java b/odata2-lib/odata-ref/src/test/java/org/apache/olingo/odata2/ref/read/EntityTest.java
index 87593f2..be55778 100644
--- a/odata2-lib/odata-ref/src/test/java/org/apache/olingo/odata2/ref/read/EntityTest.java
+++ b/odata2-lib/odata-ref/src/test/java/org/apache/olingo/odata2/ref/read/EntityTest.java
@@ -43,7 +43,7 @@ import org.apache.olingo.odata2.api.processor.ODataResponse;
 import org.apache.olingo.odata2.api.uri.KeyPredicate;
 import org.apache.olingo.odata2.api.uri.PathInfo;
 import org.apache.olingo.odata2.api.uri.UriInfo;
-import org.apache.olingo.odata2.core.annotation.ds.BeanPropertyAccess;
+import org.apache.olingo.odata2.core.annotation.data.BeanPropertyAccess;
 import org.apache.olingo.odata2.core.annotation.processor.ListsProcessor;
 import org.apache.olingo.odata2.core.commons.ContentType;
 import org.apache.olingo.odata2.ref.model.DataContainer;


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

Posted by mi...@apache.org.
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/PocEdmAnnotationsExtension
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();