You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2013/12/05 13:30:56 UTC

[03/52] git commit: Initial EdmAnnotation contribution

Initial EdmAnnotation contribution


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

Branch: refs/heads/master
Commit: ae7c1f52d812cd70354a9933e3b3cb3d61aa3186
Parents: 7ef5a9b
Author: Michael Bolz <mi...@sap.com>
Authored: Wed Oct 9 21:37:03 2013 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Thu Oct 10 13:49:47 2013 +0200

----------------------------------------------------------------------
 .gitignore                                      |   1 +
 .../edm-annotation-api/pom.xml                  |  42 ++
 .../api/annotation/edm/EdmComplexEntity.java    |  31 +
 .../api/annotation/edm/EdmComplexProperty.java  |  32 +
 .../odata2/api/annotation/edm/EdmEntitySet.java |  31 +
 .../api/annotation/edm/EdmEntityType.java       |  31 +
 .../odata2/api/annotation/edm/EdmKey.java       |  29 +
 .../annotation/edm/EdmNavigationProperty.java   |  36 +
 .../odata2/api/annotation/edm/EdmProperty.java  |  33 +
 .../odata2/api/annotation/edm/Facets.java       |  36 +
 .../api/annotation/edm/NavigationEnd.java       |  34 +
 .../api/annotation/edm/ds/EntityCreate.java     |  29 +
 .../api/annotation/edm/ds/EntityDataSource.java |  32 +
 .../api/annotation/edm/ds/EntityDelete.java     |  29 +
 .../api/annotation/edm/ds/EntityRead.java       |  29 +
 .../api/annotation/edm/ds/EntitySetRead.java    |  29 +
 .../api/annotation/edm/ds/EntityUpdate.java     |  29 +
 .../edm-annotation-core/pom.xml                 |  41 ++
 .../annotation/edm/AnnotationEdmProvider.java   | 737 +++++++++++++++++++
 .../core/annotation/edm/AnnotationHelper.java   |  62 ++
 .../odata2/core/annotation/edm/ClassHelper.java | 104 +++
 .../processor/AnnotationProcessor.java          | 439 +++++++++++
 .../processor/json/EdmAnnotationSerializer.java | 215 ++++++
 .../annotation/processor/json/JsonConsumer.java | 136 ++++
 .../annotation/processor/json/JsonWriter.java   | 256 +++++++
 .../src/main/resources/log4j.xml                |  39 +
 .../edm/AnnotationEdmProviderTest.java          | 318 ++++++++
 .../odata2/core/annotation/model/Building.java  | 100 +++
 .../odata2/core/annotation/model/City.java      |  61 ++
 .../odata2/core/annotation/model/Employee.java  | 181 +++++
 .../odata2/core/annotation/model/Location.java  |  61 ++
 .../odata2/core/annotation/model/Manager.java   |  46 ++
 .../annotation/model/ModelSharedConstants.java  |  25 +
 .../odata2/core/annotation/model/Photo.java     | 130 ++++
 .../odata2/core/annotation/model/RefBase.java   |  55 ++
 .../odata2/core/annotation/model/Room.java      |  93 +++
 .../odata2/core/annotation/model/Team.java      |  83 +++
 .../processor/json/JsonConsumerTest.java        |  85 +++
 .../edm-annotation-webref/pom.xml               | 125 ++++
 .../odata2/ref/annotation/model/Building.java   |  99 +++
 .../odata2/ref/annotation/model/City.java       |  61 ++
 .../ref/annotation/model/DataContainer.java     | 290 ++++++++
 .../odata2/ref/annotation/model/Employee.java   | 189 +++++
 .../odata2/ref/annotation/model/Location.java   |  61 ++
 .../odata2/ref/annotation/model/Manager.java    |  46 ++
 .../ref/annotation/model/ModelException.java    |  32 +
 .../annotation/model/ModelSharedConstants.java  |  25 +
 .../odata2/ref/annotation/model/Photo.java      | 131 ++++
 .../odata2/ref/annotation/model/RefBase.java    |  57 ++
 .../ref/annotation/model/ResourceHelper.java    |  61 ++
 .../odata2/ref/annotation/model/Room.java       |  97 +++
 .../odata2/ref/annotation/model/Team.java       |  83 +++
 .../ref/annotation/model/ds/BuildingDs.java     |  67 ++
 .../odata2/ref/annotation/model/ds/TeamDs.java  |  66 ++
 .../processor/ScenarioErrorCallback.java        |  47 ++
 .../processor/ScenarioServiceFactory.java       |  97 +++
 .../src/main/resources/log4j.xml                |  39 +
 .../src/main/version/version.html               |  27 +
 .../src/main/webapp/META-INF/context.xml        |   2 +
 .../src/main/webapp/WEB-INF/web.xml             |  48 ++
 .../src/main/webapp/index.jsp                   | 111 +++
 odata2-edm-annotation/pom.xml                   |  30 +
 pom.xml                                         |   1 +
 63 files changed, 5672 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 9c201f5..3f1a76b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ bin
 *.bak
 classes
 .DS_Store
+nb-configuration.xml

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/pom.xml b/odata2-edm-annotation/edm-annotation-api/pom.xml
new file mode 100644
index 0000000..5d697f2
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/pom.xml
@@ -0,0 +1,42 @@
+<?xml version="1.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.
+-->
+<project
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+  xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+	
+  <parent>
+    <groupId>org.apache.olingo</groupId>
+    <artifactId>olingo-odata2-edm-annotation-incubating</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <artifactId>olingo-odata2-edm-annotation-api-incubating</artifactId>
+  <name>${project.artifactId}</name>
+        
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-api-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmComplexEntity.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmComplexEntity.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmComplexEntity.java
new file mode 100644
index 0000000..adec2d7
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmComplexEntity.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * 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.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface EdmComplexEntity {
+  String name() default "";
+  String namespace();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmComplexProperty.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmComplexProperty.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmComplexProperty.java
new file mode 100644
index 0000000..3af0227
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmComplexProperty.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface EdmComplexProperty {
+  String name() default "";
+  String namespace() default "";
+  String facet() default "";
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmEntitySet.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmEntitySet.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmEntitySet.java
new file mode 100644
index 0000000..b62d986
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmEntitySet.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * 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.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface EdmEntitySet {
+  String name();
+  String container();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmEntityType.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmEntityType.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmEntityType.java
new file mode 100644
index 0000000..67a363d
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmEntityType.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * 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.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface EdmEntityType {
+  String name() default "";
+  String namespace();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmKey.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmKey.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmKey.java
new file mode 100644
index 0000000..48db91f
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmKey.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface EdmKey {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmNavigationProperty.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmNavigationProperty.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmNavigationProperty.java
new file mode 100644
index 0000000..cf898df
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmNavigationProperty.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * 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.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface EdmNavigationProperty {
+  String name();
+  String relationship();
+  
+  //
+  NavigationEnd from() default @NavigationEnd;
+  NavigationEnd to() default @NavigationEnd;
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmProperty.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmProperty.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmProperty.java
new file mode 100644
index 0000000..68c411b
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/EdmProperty.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * 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.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface EdmProperty {
+  EdmSimpleTypeKind type() default EdmSimpleTypeKind.Null;
+  String name() default "";
+  String facet() default "";
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/Facets.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/Facets.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/Facets.java
new file mode 100644
index 0000000..24a3be6
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/Facets.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * 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.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface Facets {
+  int maxLength() default 0;
+
+  int scale() default -1;
+
+  int precision() default 0;
+
+  boolean nullable() default false;
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/NavigationEnd.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/NavigationEnd.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/NavigationEnd.java
new file mode 100644
index 0000000..2ce5ef1
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/NavigationEnd.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * 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.api.annotation.edm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface NavigationEnd {
+  String role() default "";
+  String type() default "";
+  
+  EdmMultiplicity multiplicity() default EdmMultiplicity.ONE;
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityCreate.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityCreate.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityCreate.java
new file mode 100644
index 0000000..529ee63
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityCreate.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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.api.annotation.edm.ds;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface EntityCreate {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDataSource.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDataSource.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDataSource.java
new file mode 100644
index 0000000..aa2aff6
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDataSource.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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.api.annotation.edm.ds;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface EntityDataSource {
+  String name() default "";
+  Class<?> entityClass() default Object.class;
+  Class<?> entityType();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDelete.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDelete.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDelete.java
new file mode 100644
index 0000000..f852307
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityDelete.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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.api.annotation.edm.ds;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface EntityDelete {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityRead.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityRead.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityRead.java
new file mode 100644
index 0000000..76333ca
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityRead.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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.api.annotation.edm.ds;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface EntityRead {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntitySetRead.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntitySetRead.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntitySetRead.java
new file mode 100644
index 0000000..79cb80c
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntitySetRead.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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.api.annotation.edm.ds;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface EntitySetRead {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityUpdate.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityUpdate.java b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityUpdate.java
new file mode 100644
index 0000000..6aea1eb
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-api/src/main/java/org/apache/olingo/odata2/api/annotation/edm/ds/EntityUpdate.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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.api.annotation.edm.ds;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface EntityUpdate {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/pom.xml b/odata2-edm-annotation/edm-annotation-core/pom.xml
new file mode 100644
index 0000000..4f34c8d
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file 
+distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under 
+the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may 
+obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to 
+in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 
+ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under 
+the License. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>olingo-odata2-edm-annotation-core-incubating</artifactId>
+  <packaging>jar</packaging>
+  <name>${project.artifactId}</name>
+
+  <parent>
+    <groupId>org.apache.olingo</groupId>
+    <artifactId>olingo-odata2-edm-annotation-incubating</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-edm-annotation-api-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-api-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-core-incubating</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/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
new file mode 100644
index 0000000..419eedd
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationEdmProvider.java
@@ -0,0 +1,737 @@
+/*******************************************************************************
+ * 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.edm;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+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.EdmComplexEntity;
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexProperty;
+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.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.NavigationEnd;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.AnnotationAttribute;
+import org.apache.olingo.odata2.api.edm.provider.AnnotationElement;
+import org.apache.olingo.odata2.api.edm.provider.Association;
+import org.apache.olingo.odata2.api.edm.provider.AssociationEnd;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSet;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSetEnd;
+import org.apache.olingo.odata2.api.edm.provider.ComplexProperty;
+import org.apache.olingo.odata2.api.edm.provider.ComplexType;
+import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
+import org.apache.olingo.odata2.api.edm.provider.EntityContainer;
+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;
+import org.apache.olingo.odata2.api.edm.provider.Schema;
+import org.apache.olingo.odata2.api.edm.provider.SimpleProperty;
+import org.apache.olingo.odata2.api.edm.provider.Using;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+/**
+ * Provider for the entity data model used in the reference scenario
+ *
+ */
+public class AnnotationEdmProvider extends EdmProvider {
+
+  private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
+
+  private final List<Class<?>> annotatedClasses;
+  private final Map<String, EntityContainer> name2Container = new HashMap<String, EntityContainer>();
+  private final Map<String, ContainerBuilder> containerName2ContainerBuilder = new HashMap<String, ContainerBuilder>();
+  private final Map<String, Schema> namespace2Schema = new HashMap<String, Schema>();
+  private EntityContainer defaultContainer;
+
+  public AnnotationEdmProvider(Collection<Class<?>> annotatedClasses) {
+
+//    this.annotatedClasses = new ArrayList<Class<?>>(annotatedClasses);
+//    this.annotatedClasses.addAll(annotatedClasses);
+    this.annotatedClasses = new ArrayList<Class<?>>(annotatedClasses.size());
+    for (Class<?> aClass : annotatedClasses) {
+      if (ANNOTATION_HELPER.isEdmAnnotated(aClass)) {
+        this.annotatedClasses.add(aClass);
+      }
+    }
+
+    init();
+  }
+
+  public AnnotationEdmProvider(String packageToScan) {
+    this.annotatedClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
+      @Override
+      public boolean isClassValid(Class<?> c) {
+        return ANNOTATION_HELPER.isEdmAnnotated(c);
+      }
+    });
+    
+    init();
+  }
+
+  private void init() {
+    for (Class<?> aClass : annotatedClasses) {
+      updateSchema(aClass);
+      handleEntityContainer(aClass);
+    }
+
+    finish();
+  }
+
+  @Override
+  public Association getAssociation(FullQualifiedName edmFQName) throws ODataException {
+    Schema schema = namespace2Schema.get(edmFQName.getNamespace());
+    if (schema != null) {
+      List<Association> associations = schema.getAssociations();
+      for (Association association : associations) {
+        if (association.getName().equals(edmFQName.getName())) {
+          return association;
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public AssociationSet getAssociationSet(String entityContainer, FullQualifiedName association,
+          String sourceEntitySetName, String sourceEntitySetRole) throws ODataException {
+    EntityContainer container = name2Container.get(entityContainer);
+    if (container != null) {
+      List<AssociationSet> associations = container.getAssociationSets();
+      for (AssociationSet associationSet : associations) {
+        if (associationSet.getAssociation().equals(association)) {
+          final AssociationSetEnd endOne = associationSet.getEnd1();
+          if (endOne.getRole().equals(sourceEntitySetRole)
+                  && endOne.getEntitySet().equals(sourceEntitySetName)) {
+            return associationSet;
+          }
+          final AssociationSetEnd endTwo = associationSet.getEnd2();
+          if (endTwo.getRole().equals(sourceEntitySetRole)
+                  && endTwo.getEntitySet().equals(sourceEntitySetName)) {
+            return associationSet;
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public ComplexType getComplexType(FullQualifiedName edmFQName) throws ODataException {
+    Schema schema = namespace2Schema.get(edmFQName.getNamespace());
+    if (schema != null) {
+      List<ComplexType> complexTypes = schema.getComplexTypes();
+      for (ComplexType complexType : complexTypes) {
+        if (complexType.getName().equals(edmFQName.getName())) {
+          return complexType;
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public EntityContainerInfo getEntityContainerInfo(String name) throws ODataException {
+    EntityContainer container = name2Container.get(name);
+    if (container == null) {
+      // use default container (if set)
+      container = defaultContainer;
+    }
+    if (container != null) {
+      EntityContainerInfo info = new EntityContainerInfo();
+      info.setName(container.getName());
+      info.setDefaultEntityContainer(container.isDefaultEntityContainer());
+      info.setExtendz(container.getExtendz());
+      info.setAnnotationAttributes(container.getAnnotationAttributes());
+      info.setAnnotationElements(container.getAnnotationElements());
+
+      return info;
+    }
+
+    return null;
+  }
+
+  @Override
+  public EntitySet getEntitySet(String entityContainer, String name) throws ODataException {
+    EntityContainer container = name2Container.get(entityContainer);
+    if (container != null) {
+      List<EntitySet> entitySets = container.getEntitySets();
+      for (EntitySet entitySet : entitySets) {
+        if (entitySet.getName().equals(name)) {
+          return entitySet;
+        }
+      }
+    }
+
+    return null;
+  }
+
+  @Override
+  public EntityType getEntityType(FullQualifiedName edmFQName) throws ODataException {
+    Schema schema = namespace2Schema.get(edmFQName.getNamespace());
+    if (schema != null) {
+      List<EntityType> complexTypes = schema.getEntityTypes();
+      for (EntityType complexType : complexTypes) {
+        if (complexType.getName().equals(edmFQName.getName())) {
+          return complexType;
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public FunctionImport getFunctionImport(String entityContainer, String name) throws ODataException {
+    EntityContainer container = name2Container.get(entityContainer);
+    if (container != null) {
+      List<FunctionImport> functionImports = container.getFunctionImports();
+      for (FunctionImport functionImport : functionImports) {
+        if (functionImport.getName().equals(name)) {
+          return functionImport;
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public List<Schema> getSchemas() throws ODataException {
+    return new ArrayList<Schema>(namespace2Schema.values());
+  }
+
+  //
+  //
+  //
+  private Map<String, SchemaBuilder> namespace2SchemaBuilder = new HashMap<String, SchemaBuilder>();
+
+  private void updateSchema(Class<?> aClass) {
+    EdmEntityType et = aClass.getAnnotation(EdmEntityType.class);
+    if (et != null) {
+      updateSchema(aClass, et);
+    }
+    EdmComplexEntity ect = aClass.getAnnotation(EdmComplexEntity.class);
+    if (ect != null) {
+      updateSchema(aClass, ect);
+    }
+  }
+
+  private void updateSchema(Class<?> aClass, EdmEntityType et) {
+    String namespace = et.namespace();
+    SchemaBuilder b = namespace2SchemaBuilder.get(namespace);
+    if (b == null) {
+      b = SchemaBuilder.init(namespace);
+      namespace2SchemaBuilder.put(namespace, b);
+    }
+    TypeBuilder typeBuilder = TypeBuilder.init(et, aClass);
+    b.addEntityType(typeBuilder.buildEntityType());
+    b.addAssociations(typeBuilder.buildAssociations());
+  }
+
+  private void updateSchema(Class<?> aClass, EdmComplexEntity et) {
+    String namespace = et.namespace();
+    SchemaBuilder b = namespace2SchemaBuilder.get(namespace);
+    if (b == null) {
+      b = SchemaBuilder.init(namespace);
+      namespace2SchemaBuilder.put(namespace, b);
+    }
+    TypeBuilder typeBuilder = TypeBuilder.init(et, aClass);
+    b.addComplexType(typeBuilder.buildComplexType());
+  }
+
+  private void handleEntityContainer(Class<?> aClass) {
+    EdmEntitySet entitySet = aClass.getAnnotation(EdmEntitySet.class);
+    if (entitySet != null) {
+      EdmEntityType entity = aClass.getAnnotation(EdmEntityType.class);
+      String containerName = entitySet.container();
+      ContainerBuilder builder = containerName2ContainerBuilder.get(containerName);
+      if (builder == null) {
+        builder = ContainerBuilder.init(entity.namespace(), containerName);
+        containerName2ContainerBuilder.put(containerName, builder);
+      }
+      builder.addEntitySet(createEntitySet(entitySet, entity));
+    }
+  }
+
+  private EntitySet createEntitySet(EdmEntitySet et, EdmEntityType entity) {
+    String name = et.name();
+    FullQualifiedName typeName = new FullQualifiedName(entity.namespace(), entity.name());
+
+    return new EntitySet().setName(name).setEntityType(typeName);
+  }
+
+  private void finish() {
+    //
+    Collection<ContainerBuilder> containers = containerName2ContainerBuilder.values();
+    for (ContainerBuilder containerBuilder : containers) {
+      SchemaBuilder schemaBuilder = namespace2SchemaBuilder.get(containerBuilder.getNamespace());
+      containerBuilder.addAssociationSets(schemaBuilder.name2Associations.values());
+      final EntityContainer container = containerBuilder.build();
+      schemaBuilder.addEntityContainer(container);
+      name2Container.put(container.getName(), container);
+      if (container.isDefaultEntityContainer()) {
+        defaultContainer = container;
+      }
+    }
+    //
+    Collection<SchemaBuilder> schemaBuilders = namespace2SchemaBuilder.values();
+    for (SchemaBuilder schemaBuilder : schemaBuilders) {
+      final Schema schema = schemaBuilder.build();
+      namespace2Schema.put(schema.getNamespace(), schema);
+    }
+  }
+
+  //
+  //
+  //
+  static class TypeBuilder {
+
+    final private String namespace;
+    final private String name;
+    private boolean isAbstract = false;
+    private FullQualifiedName baseEntityType = null;
+    private final List<PropertyRef> keyProperties = new ArrayList<PropertyRef>();
+    private final List<Property> properties = new ArrayList<Property>();
+    private final List<NavigationProperty> navProperties = new ArrayList<NavigationProperty>();
+    private final List<Association> associations = new ArrayList<Association>();
+
+    public TypeBuilder(String namespace, String name) {
+      this.namespace = namespace;
+      this.name = name;
+    }
+
+    public static TypeBuilder init(EdmEntityType entity, Class<?> aClass) {
+      return new TypeBuilder(entity.namespace(), entity.name()).withClass(aClass);
+    }
+
+    public static TypeBuilder init(EdmComplexEntity entity, Class<?> aClass) {
+      return new TypeBuilder(entity.namespace(), entity.name()).withClass(aClass);
+    }
+
+    private TypeBuilder withClass(Class<?> aClass) {
+      baseEntityType = createBaseEntityFqn(aClass);
+
+      if (Modifier.isAbstract(aClass.getModifiers())) {
+        this.isAbstract = true;
+      }
+
+      Field[] fields = aClass.getDeclaredFields();
+      for (Field field : fields) {
+        EdmProperty ep = field.getAnnotation(EdmProperty.class);
+        if (ep != null) {
+          properties.add(createProperty(ep, field));
+          EdmKey eti = field.getAnnotation(EdmKey.class);
+          if (eti != null) {
+            keyProperties.add(createKeyProperty(ep, field));
+          }
+        }
+        EdmComplexProperty ecp = field.getAnnotation(EdmComplexProperty.class);
+        if (ecp != null) {
+          properties.add(createComplexProperty(ecp, field, namespace));
+        }
+        EdmNavigationProperty enp = field.getAnnotation(EdmNavigationProperty.class);
+        if (enp != null) {
+          final NavigationProperty navProperty = createNavigationProperty(namespace, enp, field);
+          navProperties.add(navProperty);
+          Association association = createAssociation(field, navProperty);
+          associations.add(association);
+        }
+      }
+
+      return this;
+    }
+
+    public TypeBuilder addProperty(PropertyRef property) {
+      keyProperties.add(property);
+      return this;
+    }
+
+    public TypeBuilder addProperty(Property property) {
+      properties.add(property);
+      return this;
+    }
+
+    public TypeBuilder addNavigationProperty(NavigationProperty property) {
+      navProperties.add(property);
+      return this;
+    }
+
+    public TypeBuilder setAbstract(boolean isAbstract) {
+      this.isAbstract = isAbstract;
+      return this;
+    }
+
+    public ComplexType buildComplexType() {
+      ComplexType complexType = new ComplexType();
+      if (baseEntityType != null) {
+        complexType.setBaseType(baseEntityType);
+      }
+      return complexType.setName(name)
+              .setProperties(properties);
+    }
+
+    public EntityType buildEntityType() {
+      EntityType entityType = new EntityType();
+      if (baseEntityType != null) {
+        entityType.setBaseType(baseEntityType);
+      }
+      if (!keyProperties.isEmpty()) {
+        entityType.setKey(new Key().setKeys(keyProperties));
+      }
+      if (!navProperties.isEmpty()) {
+        entityType.setNavigationProperties(navProperties);
+      }
+      return entityType.setName(name)
+              .setAbstract(isAbstract)
+              .setProperties(properties);
+    }
+
+    public Collection<Association> buildAssociations() {
+      return Collections.unmodifiableCollection(associations);
+    }
+
+    private PropertyRef createKeyProperty(EdmProperty et, Field field) {
+      PropertyRef keyProperty = new PropertyRef();
+      String entityName = et.name();
+      if (entityName.isEmpty()) {
+        entityName = getCanonicalName(field);
+      }
+      return keyProperty.setName(entityName);
+    }
+
+    private Property createProperty(EdmProperty ep, Field field) {
+      SimpleProperty sp = new SimpleProperty();
+      String entityName = ep.name();
+      if (entityName.isEmpty()) {
+        entityName = getCanonicalName(field);
+      }
+      sp.setName(entityName);
+      //
+      EdmSimpleTypeKind type = ep.type();
+      if (type == EdmSimpleTypeKind.Null) {
+        type = getEdmSimpleType(field.getType());
+      }
+      sp.setType(type);
+
+      return sp;
+    }
+
+    private Property createComplexProperty(EdmComplexProperty ep, Field field, String defaultNamespace) {
+      ComplexProperty cp = new ComplexProperty();
+      String entityName = ep.name();
+      if (entityName.isEmpty()) {
+        entityName = getCanonicalName(field);
+      }
+      cp.setName(entityName);
+      //
+      String entityNamespace = ep.namespace();
+      if (entityNamespace.isEmpty()) {
+        entityNamespace = defaultNamespace;
+      }
+      cp.setType(new FullQualifiedName(entityNamespace, entityName));
+
+      return cp;
+    }
+
+    private NavigationProperty createNavigationProperty(String namespace, EdmNavigationProperty enp, Field field) {
+      NavigationProperty navProp = new NavigationProperty();
+      String entityName = enp.name();
+      if (entityName.isEmpty()) {
+        entityName = getCanonicalName(field);
+      }
+      navProp.setName(entityName);
+      navProp.setRelationship(new FullQualifiedName(namespace, enp.relationship()));
+      //
+      NavigationEnd from = enp.from();
+      String fromRole = from.role();
+      if (fromRole.isEmpty()) {
+        fromRole = getCanonicalRole(field.getDeclaringClass());
+      }
+      navProp.setFromRole(fromRole);
+
+      NavigationEnd to = enp.to();
+      String toRole = to.role();
+      if (toRole.isEmpty()) {
+        toRole = getCanonicalRole(field.getType());
+      }
+      navProp.setToRole(toRole);
+
+      return navProp;
+    }
+
+    private String getCanonicalRole(Class<?> clazz) {
+      return "r_" + clazz.getSimpleName();
+    }
+
+    private EdmSimpleTypeKind getEdmSimpleType(Class<?> type) {
+      if (type == String.class) {
+        return EdmSimpleTypeKind.String;
+      } else if (type == int.class) {
+        return EdmSimpleTypeKind.Int32;
+      } else if (type == Integer.class) {
+        return EdmSimpleTypeKind.Int32;
+      } else {
+        throw new UnsupportedOperationException("Not supported type '" + type
+                + "' yet."); //To change body of generated methods, choose Tools | Templates.
+      }
+    }
+
+    private EdmEntityType checkForBaseEntity(Class<?> aClass) {
+      Class<?> superClass = aClass.getSuperclass();
+      if (superClass == Object.class) {
+        return null;
+      } else {
+        EdmEntityType edmEntity = superClass.getAnnotation(EdmEntityType.class);
+        if (edmEntity == null) {
+          return checkForBaseEntity(superClass);
+        } else {
+          return edmEntity;
+        }
+      }
+    }
+
+    private FullQualifiedName createBaseEntityFqn(Class<?> aClass) {
+      EdmEntityType baseEntity = checkForBaseEntity(aClass);
+      if (baseEntity == null) {
+        return null;
+      }
+      String beName = baseEntity.name();
+      if (beName.isEmpty()) {
+        beName = aClass.getName();
+      }
+      return new FullQualifiedName(baseEntity.namespace(), beName);
+    }
+
+    private Association createAssociation(Field field, NavigationProperty navProperty) {
+      Association a = new Association();
+      a.setName(navProperty.getRelationship().getName());
+      EdmNavigationProperty navigation = field.getAnnotation(EdmNavigationProperty.class);
+
+      NavigationEnd from = navigation.from();
+      AssociationEnd fromEnd = new AssociationEnd();
+      fromEnd.setRole(navProperty.getFromRole());
+      String typeName = from.type();
+      if (typeName.isEmpty()) {
+        typeName = name;
+      }
+      fromEnd.setType(new FullQualifiedName(namespace, typeName));
+      fromEnd.setMultiplicity(from.multiplicity());
+      a.setEnd1(fromEnd);
+
+      NavigationEnd to = navigation.to();
+      AssociationEnd toEnd = new AssociationEnd();
+      toEnd.setRole(navProperty.getToRole());
+      final FullQualifiedName toFqn;
+      if (to.type().isEmpty()) {
+        Class<?> toClass = field.getType();
+        toFqn = new FullQualifiedName(namespace, toClass.getSimpleName());
+      } else {
+        toFqn = new FullQualifiedName(namespace, to.type());
+      }
+      toEnd.setType(toFqn);
+
+      EdmMultiplicity toMultiplicity = to.multiplicity();
+      Class<?> toClass = field.getType();
+      boolean isCollectionType = toClass.isArray() || Collection.class.isAssignableFrom(toClass);
+      if (toMultiplicity == EdmMultiplicity.ONE && isCollectionType) {
+        // XXX: magic, please check and or remove/refactore
+        toEnd.setMultiplicity(EdmMultiplicity.MANY);
+      } else {
+        toEnd.setMultiplicity(toMultiplicity);
+      }
+
+      a.setEnd2(toEnd);
+
+      return a;
+    }
+
+    private String getCanonicalName(Field field) {
+      return ANNOTATION_HELPER.getCanonicalName(field);
+    }
+  }
+
+  static class SchemaBuilder {
+
+    final private String namespace;
+//    private String alias;
+    private final List<Using> usings = new ArrayList<Using>();
+    private final List<EntityType> entityTypes = new ArrayList<EntityType>();
+    private final List<ComplexType> complexTypes = new ArrayList<ComplexType>();
+    private final Map<String, Association> name2Associations = new HashMap<String, Association>();
+    private final List<EntityContainer> entityContainers = new ArrayList<EntityContainer>();
+    private final List<AnnotationAttribute> annotationAttributes = new ArrayList<AnnotationAttribute>();
+    private final List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+
+    private SchemaBuilder(String namespace) {
+      this.namespace = namespace;
+    }
+
+    public static SchemaBuilder init(String namespace) {
+      return new SchemaBuilder(namespace);
+    }
+
+    public SchemaBuilder addEntityType(EntityType type) {
+      entityTypes.add(type);
+      return this;
+    }
+
+    public SchemaBuilder addEntityContainer(EntityContainer container) {
+      entityContainers.add(container);
+      return this;
+    }
+
+    public SchemaBuilder addComplexType(ComplexType createEntityType) {
+      complexTypes.add(createEntityType);
+      return this;
+    }
+
+    public void addAssociations(Collection<Association> associations) {
+      for (Association association : associations) {
+        final String relationshipName = association.getName();
+        if (name2Associations.containsKey(relationshipName)) {
+          association = mergeAssociations(name2Associations.get(relationshipName), association);
+        }
+        name2Associations.put(relationshipName, association);
+      }
+    }
+
+    private Association mergeAssociations(Association associationOne, Association associationTwo) {
+      AssociationEnd oneEnd1 = associationOne.getEnd1();
+      AssociationEnd oneEnd2 = associationOne.getEnd2();
+      AssociationEnd twoEnd1 = associationTwo.getEnd1();
+      AssociationEnd twoEnd2 = associationTwo.getEnd2();
+      AssociationEnd[] oneEnds = new AssociationEnd[]{oneEnd1, oneEnd2};
+
+      for (AssociationEnd associationEnd : oneEnds) {
+        if (associationEnd.getRole().equals(twoEnd1.getRole())) {
+          if (twoEnd1.getMultiplicity() == EdmMultiplicity.MANY) {
+            associationEnd.setMultiplicity(EdmMultiplicity.MANY);
+          }
+        } else if (associationEnd.getRole().equals(twoEnd2.getRole())) {
+          if (twoEnd2.getMultiplicity() == EdmMultiplicity.MANY) {
+            associationEnd.setMultiplicity(EdmMultiplicity.MANY);
+          }
+        }
+      }
+
+      return associationOne;
+    }
+
+    public Schema build() {
+      Schema s = new Schema();
+      s.setUsings(usings);
+      s.setEntityTypes(entityTypes);
+      s.setComplexTypes(complexTypes);
+      s.setAssociations(new ArrayList<Association>(name2Associations.values()));
+      s.setEntityContainers(entityContainers);
+      s.setAnnotationAttributes(annotationAttributes);
+      s.setAnnotationElements(annotationElements);
+      s.setNamespace(namespace);
+      return s;
+    }
+  }
+
+  private static class ContainerBuilder {
+
+    final private String name;
+    final private String namespace;
+    private boolean defaultContainer = true;
+    private List<EntitySet> entitySets = new ArrayList<EntitySet>();
+    private List<AssociationSet> associationSets = new ArrayList<AssociationSet>();
+    private List<FunctionImport> functionImports = new ArrayList<FunctionImport>();
+//    private Documentation documentation;
+
+    private ContainerBuilder(String namespace, String containerName) {
+      this.namespace = namespace;
+      name = containerName;
+    }
+
+    public String getNamespace() {
+      return namespace;
+    }
+
+    public static ContainerBuilder init(String namespace, String containerName) {
+      return new ContainerBuilder(namespace, containerName);
+    }
+
+    public ContainerBuilder setDefaultContainer(boolean isDefault) {
+      defaultContainer = isDefault;
+      return this;
+    }
+
+    public ContainerBuilder addEntitySet(EntitySet entitySet) {
+      entitySets.add(entitySet);
+      return this;
+    }
+    
+    public void addAssociationSets(Collection<Association> associations) {
+      for (Association association : associations) {
+        AssociationSet as = new AssociationSet();
+        as.setName(association.getName());
+        FullQualifiedName asAssociationFqn = new FullQualifiedName(namespace, association.getName());
+        as.setAssociation(asAssociationFqn);
+
+        AssociationSetEnd asEnd1 = new AssociationSetEnd();
+        asEnd1.setEntitySet(getEntitySetName(association.getEnd1()));
+        asEnd1.setRole(association.getEnd1().getRole());
+        as.setEnd1(asEnd1);
+        
+        AssociationSetEnd asEnd2 = new AssociationSetEnd();
+        asEnd2.setEntitySet(getEntitySetName(association.getEnd2()));
+        asEnd2.setRole(association.getEnd2().getRole());
+        as.setEnd2(asEnd2);
+        
+        associationSets.add(as);
+      }
+    }
+
+    public EntityContainer build() {
+      EntityContainer ec = new EntityContainer();
+      ec.setName(name);
+      ec.setDefaultEntityContainer(defaultContainer);
+      ec.setEntitySets(entitySets);
+      ec.setAssociationSets(associationSets);
+      ec.setFunctionImports(functionImports);
+      return ec;
+    }
+
+    private String getEntitySetName(AssociationEnd end) {
+      for (EntitySet entitySet : entitySets) {
+        if(entitySet.getEntityType().equals(end.getType())) {
+          return entitySet.getName();
+        }
+      }
+      throw new ODataRuntimeException("No entity set found for " + end.getType());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/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
new file mode 100644
index 0000000..184685e
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * 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.edm;
+
+import java.lang.reflect.Field;
+import java.util.Locale;
+import org.apache.olingo.odata2.api.annotation.edm.EdmComplexEntity;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+
+/**
+ *
+ */
+public class AnnotationHelper {
+
+  public boolean isEdmAnnotated(Object object) {
+    if(object == null) {
+      return false;
+    }
+    return isEdmAnnotated(object.getClass());
+  }
+  
+  public boolean isEdmAnnotated(Class<?> clazz) {
+    if (clazz == null) {
+      return false;
+    } else {
+      final boolean isEntity = null != clazz.getAnnotation(EdmEntityType.class);
+      final boolean isComplexEntity = null != clazz.getAnnotation(EdmComplexEntity.class);
+      return isEntity || isComplexEntity;
+    }
+  }
+  
+  public String getCanonicalName(Field field) {
+    return firstCharToUpperCase(field.getName());
+  }
+  
+  public String getCanonicalName(Class<?> clazz) {
+    return firstCharToUpperCase(clazz.getSimpleName());
+  }
+  
+  private String firstCharToUpperCase(String content) {
+    if(content == null || content.isEmpty()) {
+      return content;
+    }
+    return content.substring(0, 1).toUpperCase(Locale.ENGLISH) + content.substring(1);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ae7c1f52/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/ClassHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/ClassHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/ClassHelper.java
new file mode 100644
index 0000000..baf4626
--- /dev/null
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/ClassHelper.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * 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.edm;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FilenameFilter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ */
+public class ClassHelper {
+  
+  private static final File[] EMPTY_FILE_ARRAY = new File[0];
+  
+  private static final FilenameFilter CLASSFILE_FILTER = new FilenameFilter() {
+    @Override
+    public boolean accept(File dir, String name) {
+      return name.endsWith(CLASSFILE_ENDING);
+    }
+    public static final String CLASSFILE_ENDING = ".class";
+  };
+  
+  private static final FileFilter FOLDER_FILTER = new FileFilter() {
+    @Override
+    public boolean accept(File pathname) {
+      return pathname.isDirectory();
+    }
+  };
+  
+  public static final List<Class<?>> loadClasses(String packageToScan, ClassValidator cv) {
+    return loadClasses(packageToScan, CLASSFILE_FILTER, cv);
+  }
+
+  
+  public static final List<Class<?>> loadClasses(String packageToScan, FilenameFilter ff, ClassValidator cv) {
+    final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+    String folderToScan = packageToScan.replace(".", "/");
+    URL url = classLoader.getResource(folderToScan);
+    if(url == null) {
+      throw new IllegalArgumentException("No folder to scan found for package '" + packageToScan + "'.");
+    }
+    File folder = new File(url.getFile());
+    File[] classFiles = folder.listFiles(ff);
+    if(classFiles == null) {
+      classFiles = EMPTY_FILE_ARRAY;
+    }
+
+    List<Class<?>> annotatedClasses = new ArrayList<Class<?>>(classFiles.length);
+    for (File file : classFiles) {
+      String name = file.getName();
+      String fqn = packageToScan + "." + name.substring(0, name.length() - 6);
+      try {
+        Class<?> c = classLoader.loadClass(fqn);
+        if (cv.isClassValid(c)) {
+          annotatedClasses.add(c);
+        }
+      } catch (ClassNotFoundException ex) {
+      }
+    }
+    
+    // recursive search
+    File[] subfolders = listSubFolder(folder);
+    for (File file : subfolders) {
+      List<Class<?>> subFolderClazzes = loadClasses(packageToScan + "." + file.getName(), ff, cv);
+      annotatedClasses.addAll(subFolderClazzes);
+    }
+    //
+    
+    return annotatedClasses;
+  }
+
+  private static File[] listSubFolder(File folder) {
+    File[] subfolders = folder.listFiles(FOLDER_FILTER);
+    if(subfolders == null) {
+      return EMPTY_FILE_ARRAY;
+    }
+    return subfolders;
+  }
+  
+  public interface ClassValidator {
+    boolean isClassValid(Class<?> c);
+  }
+}