You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by fm...@apache.org on 2013/07/26 13:22:48 UTC

[43/51] [partial] initial commit

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmBaseViewImpl.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmBaseViewImpl.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmBaseViewImpl.java
new file mode 100644
index 0000000..4070032
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmBaseViewImpl.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.model;
+
+import javax.persistence.metamodel.Metamodel;
+
+import org.apache.olingo.odata2.processor.api.jpa.ODataJPAContext;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmMappingModelAccess;
+import org.apache.olingo.odata2.processor.api.jpa.factory.ODataJPAFactory;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmBaseView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmExtension;
+
+public abstract class JPAEdmBaseViewImpl implements JPAEdmBaseView {
+
+  protected String pUnitName = null;
+  protected Metamodel metaModel = null;
+  protected boolean isConsistent = true;
+  protected JPAEdmBuilder builder = null;
+  protected JPAEdmExtension jpaEdmExtension = null;
+  private JPAEdmMappingModelAccess jpaEdmMappingModelAccess = null;
+
+  public JPAEdmBaseViewImpl(final JPAEdmBaseView view) {
+    pUnitName = view.getpUnitName();
+    metaModel = view.getJPAMetaModel();
+    jpaEdmMappingModelAccess = view.getJPAEdmMappingModelAccess();
+    jpaEdmExtension = view.getJPAEdmExtension();
+  }
+
+  public JPAEdmBaseViewImpl(final ODataJPAContext context) {
+    pUnitName = context.getPersistenceUnitName();
+    metaModel = context.getEntityManagerFactory().getMetamodel();
+    jpaEdmMappingModelAccess = ODataJPAFactory.createFactory()
+        .getJPAAccessFactory().getJPAEdmMappingModelAccess(context);
+    jpaEdmExtension = context.getJPAEdmExtension();
+    jpaEdmMappingModelAccess.loadMappingModel();
+  }
+
+  public JPAEdmBaseViewImpl(final Metamodel metaModel, final String pUnitName) {
+    this.metaModel = metaModel;
+    this.pUnitName = pUnitName;
+  }
+
+  @Override
+  public String getpUnitName() {
+    return pUnitName;
+  }
+
+  @Override
+  public Metamodel getJPAMetaModel() {
+    return metaModel;
+  }
+
+  @Override
+  public boolean isConsistent() {
+    return isConsistent;
+  }
+
+  @Override
+  public void clean() {
+    pUnitName = null;
+    metaModel = null;
+    isConsistent = false;
+  }
+
+  @Override
+  public JPAEdmMappingModelAccess getJPAEdmMappingModelAccess() {
+    return jpaEdmMappingModelAccess;
+
+  }
+
+  @Override
+  public JPAEdmExtension getJPAEdmExtension() {
+    return jpaEdmExtension;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmComplexType.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmComplexType.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmComplexType.java
new file mode 100644
index 0000000..a68dbc6
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmComplexType.java
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.EmbeddableType;
+
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+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.Mapping;
+import org.apache.olingo.odata2.api.edm.provider.Property;
+import org.apache.olingo.odata2.api.edm.provider.SimpleProperty;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmMappingModelAccess;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmComplexTypeView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmMapping;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmPropertyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmSchemaView;
+import org.apache.olingo.odata2.processor.core.jpa.access.model.JPAEdmNameBuilder;
+
+public class JPAEdmComplexType extends JPAEdmBaseViewImpl implements
+    JPAEdmComplexTypeView {
+
+  private JPAEdmSchemaView schemaView;
+  private ComplexType currentComplexType = null;
+  private EmbeddableType<?> currentEmbeddableType = null;
+  private HashMap<String, ComplexType> searchMap = null;
+  private List<ComplexType> consistentComplextTypes = null;
+  private boolean directBuild;
+  private EmbeddableType<?> nestedComplexType = null;
+
+  public JPAEdmComplexType(final JPAEdmSchemaView view) {
+    super(view);
+    schemaView = view;
+    directBuild = true;
+  }
+
+  public JPAEdmComplexType(final JPAEdmSchemaView view, final Attribute<?, ?> complexAttribute) {
+    super(view);
+    schemaView = view;
+    for (EmbeddableType<?> jpaEmbeddable : schemaView.getJPAMetaModel().getEmbeddables())
+    {
+      if (jpaEmbeddable.getJavaType().getName().equals(complexAttribute.getJavaType().getName()))
+      {
+        nestedComplexType = jpaEmbeddable;
+        break;
+      }
+    }
+    directBuild = false;
+  }
+
+  @Override
+  public JPAEdmBuilder getBuilder() {
+    if (builder == null) {
+      builder = new JPAEdmComplexTypeBuilder();
+    }
+
+    return builder;
+  }
+
+  @Override
+  public ComplexType getEdmComplexType() {
+    return currentComplexType;
+  }
+
+  @Override
+  public ComplexType searchEdmComplexType(final String embeddableTypeName) {
+    return searchMap.get(embeddableTypeName);
+  }
+
+  @Override
+  public EmbeddableType<?> getJPAEmbeddableType() {
+    return currentEmbeddableType;
+  }
+
+  @Override
+  public List<ComplexType> getConsistentEdmComplexTypes() {
+    return consistentComplextTypes;
+  }
+
+  @Override
+  public ComplexType searchEdmComplexType(final FullQualifiedName type) {
+    String name = type.getName();
+    return searchComplexTypeByName(name);
+
+  }
+
+  private ComplexType searchComplexTypeByName(final String name) {
+    for (ComplexType complexType : consistentComplextTypes) {
+      if (null != complexType && null != complexType.getName() && complexType.getName().equals(name)) {
+        return complexType;
+      }
+    }
+
+    return null;
+  }
+
+  @Override
+  public void addJPAEdmCompleTypeView(final JPAEdmComplexTypeView view) {
+    String searchKey = view.getJPAEmbeddableType().getJavaType().getName();
+
+    if (!searchMap.containsKey(searchKey)) {
+      consistentComplextTypes.add(view.getEdmComplexType());
+      searchMap.put(searchKey, view.getEdmComplexType());
+    }
+  }
+
+  @Override
+  public void expandEdmComplexType(final ComplexType complexType, List<Property> expandedList, final String embeddablePropertyName) {
+
+    if (expandedList == null) {
+      expandedList = new ArrayList<Property>();
+    }
+    for (Property property : complexType.getProperties())
+    {
+      try {
+        SimpleProperty newSimpleProperty = new SimpleProperty();
+        SimpleProperty oldSimpleProperty = (SimpleProperty) property;
+        newSimpleProperty.setAnnotationAttributes(oldSimpleProperty.getAnnotationAttributes());
+        newSimpleProperty.setAnnotationElements(oldSimpleProperty.getAnnotationElements());
+        newSimpleProperty.setCustomizableFeedMappings(oldSimpleProperty.getCustomizableFeedMappings());
+        newSimpleProperty.setDocumentation(oldSimpleProperty.getDocumentation());
+        newSimpleProperty.setFacets(oldSimpleProperty.getFacets());
+        newSimpleProperty.setMimeType(oldSimpleProperty.getMimeType());
+        newSimpleProperty.setName(oldSimpleProperty.getName());
+        newSimpleProperty.setType(oldSimpleProperty.getType());
+        JPAEdmMappingImpl newMapping = new JPAEdmMappingImpl();
+        Mapping mapping = oldSimpleProperty.getMapping();
+        JPAEdmMapping oldMapping = (JPAEdmMapping) mapping;
+        newMapping.setJPAColumnName(oldMapping.getJPAColumnName());
+        newMapping.setInternalName(embeddablePropertyName + "." + mapping.getInternalName());
+        newMapping.setMimeType(mapping.getMimeType());
+        newMapping.setObject(mapping.getObject());
+        newSimpleProperty.setMapping(newMapping);
+        expandedList.add(newSimpleProperty);
+      } catch (ClassCastException e) {
+        ComplexProperty complexProperty = (ComplexProperty) property;
+        String name = complexProperty.getMapping().getInternalName();
+        expandEdmComplexType(searchComplexTypeByName(complexProperty.getName()), expandedList, name);
+      }
+    }
+
+  }
+
+  private class JPAEdmComplexTypeBuilder implements JPAEdmBuilder {
+    /*
+     * 
+     * Each call to build method creates a new Complex Type.
+     * The Complex Type is created only if it is not created
+     * earlier. A local buffer is maintained to track the list
+     * of complex types created.
+     *  
+     * ************************************************************
+     * 				Build EDM Complex Type - STEPS
+     * ************************************************************
+     * 1) Fetch list of embeddable types from JPA Model
+     * 2) Search local buffer if there exists already a Complex 
+     * type for the embeddable type. 
+     * 3) If the complex type was already been built continue with
+     * the next embeddable type, else create new EDM Complex Type.
+     * 4) Create a Property view with Complex Type
+     * 5) Get Property Builder and build the Property with Complex
+     * type.
+     * 6) Set EDM complex type with list of properties built by
+     * the property view
+     * 7) Provide name for EDM complex type.
+     * 
+     * ************************************************************
+     * 				Build EDM Complex Type - STEPS
+     * ************************************************************
+     *
+     */
+    @Override
+    public void build() throws ODataJPAModelException, ODataJPARuntimeException {
+      Set<EmbeddableType<?>> embeddables = new HashSet<EmbeddableType<?>>();
+
+      if (consistentComplextTypes == null) {
+        consistentComplextTypes = new ArrayList<ComplexType>();
+      }
+
+      if (searchMap == null) {
+        searchMap = new HashMap<String, ComplexType>();
+      }
+
+      if (directBuild) {
+        embeddables = schemaView.getJPAMetaModel().getEmbeddables();
+      } else {
+        embeddables.add(nestedComplexType);
+      }
+
+      for (EmbeddableType<?> embeddableType : embeddables) {
+
+        currentEmbeddableType = embeddableType;
+        String searchKey = embeddableType.getJavaType().getName();
+
+        if (searchMap.containsKey(searchKey)) {
+          continue;
+        }
+
+        // Check for need to Exclude
+        if (isExcluded(JPAEdmComplexType.this)) {
+          continue;
+        }
+
+        JPAEdmPropertyView propertyView = new JPAEdmProperty(
+            schemaView, JPAEdmComplexType.this);
+        propertyView.getBuilder().build();
+
+        currentComplexType = new ComplexType();
+        currentComplexType
+            .setProperties(propertyView.getEdmPropertyList());
+        JPAEdmNameBuilder.build(JPAEdmComplexType.this);
+
+        searchMap.put(searchKey, currentComplexType);
+        consistentComplextTypes.add(currentComplexType);
+
+      }
+
+    }
+
+    private boolean isExcluded(final JPAEdmComplexType jpaEdmComplexType) {
+
+      JPAEdmMappingModelAccess mappingModelAccess = jpaEdmComplexType
+          .getJPAEdmMappingModelAccess();
+      if (mappingModelAccess != null
+          && mappingModelAccess.isMappingModelExists()
+          && mappingModelAccess.checkExclusionOfJPAEmbeddableType(jpaEdmComplexType.getJPAEmbeddableType()
+              .getJavaType().getSimpleName())) {
+        return true;
+      }
+      return false;
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntityContainer.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntityContainer.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntityContainer.java
new file mode 100644
index 0000000..587c2ef
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntityContainer.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.provider.EntityContainer;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmAssociationSetView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntityContainerView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntitySetView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmFunctionImportView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmSchemaView;
+import org.apache.olingo.odata2.processor.core.jpa.access.model.JPAEdmNameBuilder;
+
+public class JPAEdmEntityContainer extends JPAEdmBaseViewImpl implements
+    JPAEdmEntityContainerView {
+
+  private JPAEdmEntitySetView entitySetView;
+  private JPAEdmSchemaView schemaView;
+  private JPAEdmAssociationSetView associationSetView;
+
+  private EntityContainer currentEntityContainer;
+  private List<EntityContainer> consistentEntityContainerList;
+
+  public JPAEdmEntityContainer(final JPAEdmSchemaView view) {
+    super(view);
+    schemaView = view;
+  }
+
+  @Override
+  public JPAEdmBuilder getBuilder() {
+    if (builder == null) {
+      builder = new JPAEdmEntityContainerBuilder();
+    }
+
+    return builder;
+  }
+
+  @Override
+  public EntityContainer getEdmEntityContainer() {
+    return currentEntityContainer;
+  }
+
+  @Override
+  public List<EntityContainer> getConsistentEdmEntityContainerList() {
+    return consistentEntityContainerList;
+  }
+
+  @Override
+  public JPAEdmEntitySetView getJPAEdmEntitySetView() {
+    return entitySetView;
+  }
+
+  @Override
+  public JPAEdmAssociationSetView getEdmAssociationSetView() {
+    return associationSetView;
+  }
+
+  @Override
+  public void clean() {
+    super.clean();
+    entitySetView = null;
+    associationSetView = null;
+    currentEntityContainer = null;
+    consistentEntityContainerList = null;
+  }
+
+  private class JPAEdmEntityContainerBuilder implements JPAEdmBuilder {
+    /*
+     * 
+     * Each call to build method creates a new Entity Container and builds
+     * the entity container with Association Sets and Entity Sets. The newly
+     * created and built entity container is added to the exiting Entity
+     * Container List.
+     * 
+     * ************************************************************ Build
+     * EDM Entity Container - STEPS
+     * ************************************************************ 1)
+     * Instantiate New EDM Entity Container 2) Build Name for EDM Entity
+     * Container 2) Create Entity Container List (if does not exists) 3)
+     * Build EDM Entity Set 4) Add EDM Entity Set to EDM Entity Container 6)
+     * Build EDM Association Set 7) Add EDM Association Set to EDM Entity
+     * Container 8) Add EDM Entity Container to the Container List
+     * ************************************************************ Build
+     * EDM Entity Container - STEPS
+     * ************************************************************
+     */
+    @Override
+    public void build() throws ODataJPAModelException,
+        ODataJPARuntimeException {
+
+      currentEntityContainer = new EntityContainer();
+
+      if (consistentEntityContainerList == null) {
+        currentEntityContainer.setDefaultEntityContainer(true);
+        consistentEntityContainerList = new ArrayList<EntityContainer>();
+      }
+
+      entitySetView = new JPAEdmEntitySet(schemaView);
+      entitySetView.getBuilder().build();
+      if (entitySetView.isConsistent()) {
+        currentEntityContainer.setEntitySets(entitySetView
+            .getConsistentEdmEntitySetList());
+      } else {
+        isConsistent = false;
+        return;
+      }
+
+      if (!schemaView.getJPAEdmAssociationView().isConsistent()) {
+        schemaView.getJPAEdmAssociationView().getBuilder().build();
+      }
+
+      associationSetView = new JPAEdmAssociationSet(schemaView);
+      associationSetView.getBuilder().build();
+      if (associationSetView.isConsistent()) {
+        currentEntityContainer.setAssociationSets(associationSetView
+            .getConsistentEdmAssociationSetList());
+      } else {
+        isConsistent = false;
+        return;
+      }
+
+      JPAEdmNameBuilder.build(JPAEdmEntityContainer.this);
+      if (schemaView.getJPAEdmExtension() != null) {
+        JPAEdmFunctionImportView functionImportView = new JPAEdmFunctionImport(
+            schemaView);
+        functionImportView.getBuilder().build();
+        if (functionImportView.getConsistentFunctionImportList() != null) {
+          currentEntityContainer
+              .setFunctionImports(functionImportView
+                  .getConsistentFunctionImportList());
+        }
+      }
+
+      consistentEntityContainerList.add(currentEntityContainer);
+      isConsistent = true;
+
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntitySet.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntitySet.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntitySet.java
new file mode 100644
index 0000000..d79ac2d
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntitySet.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.EntitySet;
+import org.apache.olingo.odata2.api.edm.provider.EntityType;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntitySetView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntityTypeView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmSchemaView;
+import org.apache.olingo.odata2.processor.core.jpa.access.model.JPAEdmNameBuilder;
+
+public class JPAEdmEntitySet extends JPAEdmBaseViewImpl implements
+    JPAEdmEntitySetView {
+
+  private EntitySet currentEntitySet = null;
+  private List<EntitySet> consistentEntitySetList = null;
+  private JPAEdmEntityTypeView entityTypeView = null;
+  private JPAEdmSchemaView schemaView;
+
+  public JPAEdmEntitySet(final JPAEdmSchemaView view) {
+    super(view);
+    schemaView = view;
+  }
+
+  @Override
+  public JPAEdmBuilder getBuilder() {
+    if (builder == null) {
+      builder = new JPAEdmEntitySetBuilder();
+    }
+
+    return builder;
+  }
+
+  @Override
+  public EntitySet getEdmEntitySet() {
+    return currentEntitySet;
+  }
+
+  @Override
+  public List<EntitySet> getConsistentEdmEntitySetList() {
+    return consistentEntitySetList;
+  }
+
+  @Override
+  public JPAEdmEntityTypeView getJPAEdmEntityTypeView() {
+    return entityTypeView;
+  }
+
+  @Override
+  public void clean() {
+    currentEntitySet = null;
+    consistentEntitySetList = null;
+    entityTypeView = null;
+    isConsistent = false;
+  }
+
+  private class JPAEdmEntitySetBuilder implements JPAEdmBuilder {
+
+    @Override
+    public void build() throws ODataJPAModelException, ODataJPARuntimeException {
+
+      if (consistentEntitySetList == null) {
+        consistentEntitySetList = new ArrayList<EntitySet>();
+      }
+
+      entityTypeView = new JPAEdmEntityType(schemaView);
+      entityTypeView.getBuilder().build();
+
+      if (entityTypeView.isConsistent() && entityTypeView.getConsistentEdmEntityTypes() != null) {
+
+        String nameSpace = schemaView.getEdmSchema().getNamespace();
+        for (EntityType entityType : entityTypeView
+            .getConsistentEdmEntityTypes()) {
+
+          currentEntitySet = new EntitySet();
+          currentEntitySet.setEntityType(new FullQualifiedName(
+              nameSpace, entityType.getName()));
+          JPAEdmNameBuilder.build(JPAEdmEntitySet.this, entityTypeView);
+          consistentEntitySetList.add(currentEntitySet);
+
+        }
+        isConsistent = true;
+      } else {
+        isConsistent = false;
+        return;
+      }
+
+    }
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntityType.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntityType.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntityType.java
new file mode 100644
index 0000000..7bb5a5c
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntityType.java
@@ -0,0 +1,242 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+
+import org.apache.olingo.odata2.api.edm.provider.EntityType;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmMappingModelAccess;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntityTypeView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmKeyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmNavigationPropertyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmPropertyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmSchemaView;
+import org.apache.olingo.odata2.processor.core.jpa.access.model.JPAEdmNameBuilder;
+
+public class JPAEdmEntityType extends JPAEdmBaseViewImpl implements
+    JPAEdmEntityTypeView {
+
+  private JPAEdmSchemaView schemaView = null;
+  private EntityType currentEdmEntityType = null;
+  private javax.persistence.metamodel.EntityType<?> currentJPAEntityType = null;
+  private EntityTypeList<EntityType> consistentEntityTypes = null;
+
+  private HashMap<String, EntityType> consistentEntityTypeMap;
+
+  public JPAEdmEntityType(final JPAEdmSchemaView view) {
+    super(view);
+    schemaView = view;
+    consistentEntityTypeMap = new HashMap<String, EntityType>();
+  }
+
+  @Override
+  public JPAEdmBuilder getBuilder() {
+    if (builder == null) {
+      builder = new JPAEdmEntityTypeBuilder();
+    }
+
+    return builder;
+  }
+
+  @Override
+  public EntityType getEdmEntityType() {
+    return currentEdmEntityType;
+  }
+
+  @Override
+  public javax.persistence.metamodel.EntityType<?> getJPAEntityType() {
+    return currentJPAEntityType;
+  }
+
+  @Override
+  public List<EntityType> getConsistentEdmEntityTypes() {
+    return consistentEntityTypes;
+  }
+
+  @Override
+  public EntityType searchEdmEntityType(final String jpaEntityTypeName) {
+    return consistentEntityTypeMap.get(jpaEntityTypeName);
+  }
+
+  private class JPAEdmEntityTypeBuilder implements JPAEdmBuilder {
+
+    @Override
+    public void build() throws ODataJPAModelException,
+        ODataJPARuntimeException {
+
+      Set<javax.persistence.metamodel.EntityType<?>> jpaEntityTypes = metaModel
+          .getEntities();
+
+      if (jpaEntityTypes == null || jpaEntityTypes.isEmpty() == true) {
+        return;
+      } else if (consistentEntityTypes == null) {
+        consistentEntityTypes = new EntityTypeList<EntityType>();
+
+      }
+
+      for (javax.persistence.metamodel.EntityType<?> jpaEntityType : jpaEntityTypes) {
+        currentEdmEntityType = new EntityType();
+        currentJPAEntityType = jpaEntityType;
+
+        // Check for need to Exclude
+        if (isExcluded(JPAEdmEntityType.this)) {
+          continue;
+        }
+
+        JPAEdmNameBuilder.build(JPAEdmEntityType.this);
+
+        JPAEdmPropertyView propertyView = new JPAEdmProperty(schemaView);
+        propertyView.getBuilder().build();
+
+        currentEdmEntityType.setProperties(propertyView
+            .getEdmPropertyList());
+        if (propertyView.getJPAEdmNavigationPropertyView() != null) {
+          JPAEdmNavigationPropertyView navPropView = propertyView
+              .getJPAEdmNavigationPropertyView();
+          if (navPropView.getConsistentEdmNavigationProperties() != null
+              && !navPropView
+                  .getConsistentEdmNavigationProperties()
+                  .isEmpty()) {
+            currentEdmEntityType
+                .setNavigationProperties(navPropView
+                    .getConsistentEdmNavigationProperties());
+          }
+        }
+        JPAEdmKeyView keyView = propertyView.getJPAEdmKeyView();
+        currentEdmEntityType.setKey(keyView.getEdmKey());
+
+        consistentEntityTypes.add(currentEdmEntityType);
+        consistentEntityTypeMap.put(currentJPAEntityType.getName(),
+            currentEdmEntityType);
+      }
+
+    }
+
+    private boolean isExcluded(final JPAEdmEntityType jpaEdmEntityType) {
+      JPAEdmMappingModelAccess mappingModelAccess = jpaEdmEntityType
+          .getJPAEdmMappingModelAccess();
+      if (mappingModelAccess != null
+          && mappingModelAccess.isMappingModelExists()
+          && mappingModelAccess.checkExclusionOfJPAEntityType(jpaEdmEntityType.getJPAEntityType().getName())) {
+        return true;
+      }
+      return false;
+    }
+
+  }
+
+  private class EntityTypeList<X> extends ArrayList<EntityType> {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 719079109608251592L;
+
+    @Override
+    public Iterator<EntityType> iterator() {
+      return new EntityTypeListIterator<X>(size());
+    }
+
+  }
+
+  private class EntityTypeListIterator<E> implements ListIterator<EntityType> {
+
+    private int size = 0;
+    private int pos = 0;
+
+    public EntityTypeListIterator(final int listSize) {
+      this.size = listSize;
+    }
+
+    @Override
+    public void add(final EntityType e) {
+      consistentEntityTypes.add(e);
+      size++;
+    }
+
+    @Override
+    public boolean hasNext() {
+      if (pos < size) {
+        return true;
+      }
+
+      return false;
+    }
+
+    @Override
+    public boolean hasPrevious() {
+      if (pos > 0) {
+        return true;
+      }
+      return false;
+    }
+
+    @Override
+    public EntityType next() {
+      if (pos < size) {
+        currentEdmEntityType = consistentEntityTypes.get(pos++);
+        return currentEdmEntityType;
+      }
+
+      return null;
+    }
+
+    @Override
+    public int nextIndex() {
+      return pos;
+    }
+
+    @Override
+    public EntityType previous() {
+      if (pos > 0 && pos < size) {
+        currentEdmEntityType = consistentEntityTypes.get(--pos);
+        return currentEdmEntityType;
+      }
+      return null;
+    }
+
+    @Override
+    public int previousIndex() {
+      if (pos > 0) {
+        return pos - 1;
+      }
+
+      return 0;
+    }
+
+    @Override
+    public void remove() {
+      consistentEntityTypes.remove(pos);
+    }
+
+    @Override
+    public void set(final EntityType e) {
+      consistentEntityTypes.set(pos, e);
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmFunctionImport.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmFunctionImport.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmFunctionImport.java
new file mode 100644
index 0000000..ad12196
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmFunctionImport.java
@@ -0,0 +1,357 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.model;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.annotation.edm.FunctionImport.Multiplicity;
+import org.apache.olingo.odata2.api.annotation.edm.FunctionImport.ReturnType;
+import org.apache.olingo.odata2.api.annotation.edm.Parameter;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.edm.provider.ComplexType;
+import org.apache.olingo.odata2.api.edm.provider.EntityType;
+import org.apache.olingo.odata2.api.edm.provider.Facets;
+import org.apache.olingo.odata2.api.edm.provider.FunctionImport;
+import org.apache.olingo.odata2.api.edm.provider.FunctionImportParameter;
+import org.apache.olingo.odata2.api.edm.provider.Mapping;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmComplexTypeView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntityTypeView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmFunctionImportView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmMapping;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmSchemaView;
+import org.apache.olingo.odata2.processor.core.jpa.access.model.JPAEdmNameBuilder;
+import org.apache.olingo.odata2.processor.core.jpa.access.model.JPATypeConvertor;
+
+public class JPAEdmFunctionImport extends JPAEdmBaseViewImpl implements
+    JPAEdmFunctionImportView {
+
+  private List<FunctionImport> consistentFunctionImportList = new ArrayList<FunctionImport>();
+  private JPAEdmBuilder builder = null;
+  private JPAEdmSchemaView schemaView;
+
+  public JPAEdmFunctionImport(final JPAEdmSchemaView view) {
+    super(view);
+    schemaView = view;
+  }
+
+  @Override
+  public JPAEdmBuilder getBuilder() {
+    if (builder == null) {
+      builder = new JPAEdmFunctionImportBuilder();
+    }
+    return builder;
+  }
+
+  @Override
+  public List<FunctionImport> getConsistentFunctionImportList() {
+    return consistentFunctionImportList;
+  }
+
+  protected class JPAEdmFunctionImportBuilder implements JPAEdmBuilder {
+
+    private JPAEdmEntityTypeView jpaEdmEntityTypeView = null;
+    private JPAEdmComplexTypeView jpaEdmComplexTypeView = null;
+
+    @Override
+    public void build() throws ODataJPAModelException,
+        ODataJPARuntimeException {
+
+      HashMap<Class<?>, String[]> customOperations = schemaView
+          .getRegisteredOperations();
+
+      jpaEdmEntityTypeView = schemaView.getJPAEdmEntityContainerView()
+          .getJPAEdmEntitySetView().getJPAEdmEntityTypeView();
+      jpaEdmComplexTypeView = schemaView.getJPAEdmComplexTypeView();
+
+      if (customOperations != null) {
+
+        for (Class<?> clazz : customOperations.keySet()) {
+
+          String[] operationNames = customOperations.get(clazz);
+          Method[] methods = clazz.getMethods();
+          Method method = null;
+
+          int length = 0;
+          if (operationNames != null) {
+            length = operationNames.length;
+          } else {
+            length = methods.length;
+          }
+
+          boolean found = false;
+          for (int i = 0; i < length; i++) {
+
+            try {
+              if (operationNames != null) {
+                for (Method method2 : methods) {
+                  if (method2.getName().equals(
+                      operationNames[i])) {
+                    found = true;
+                    method = method2;
+                    break;
+                  }
+                }
+                if (found == true) {
+                  found = false;
+                } else {
+                  continue;
+                }
+              } else {
+                method = methods[i];
+              }
+
+              FunctionImport functionImport = buildFunctionImport(method);
+              if (functionImport != null) {
+                consistentFunctionImportList
+                    .add(functionImport);
+              }
+
+            } catch (SecurityException e) {
+              throw ODataJPAModelException.throwException(
+                  ODataJPAModelException.GENERAL, e);
+            }
+          }
+        }
+      }
+    }
+
+    private FunctionImport buildFunctionImport(final Method method)
+        throws ODataJPAModelException {
+
+      org.apache.olingo.odata2.api.annotation.edm.FunctionImport annotation = method
+          .getAnnotation(org.apache.olingo.odata2.api.annotation.edm.FunctionImport.class);
+      if (annotation != null && annotation.returnType() != ReturnType.NONE) {
+        FunctionImport functionImport = new FunctionImport();
+
+        if (annotation.name().equals("")) {
+          functionImport.setName(method.getName());
+        } else {
+          functionImport.setName(annotation.name());
+        }
+
+        JPAEdmMapping mapping = new JPAEdmMappingImpl();
+        ((Mapping) mapping).setInternalName(method.getName());
+        mapping.setJPAType(method.getDeclaringClass());
+        functionImport.setMapping((Mapping) mapping);
+
+        functionImport.setHttpMethod(annotation.httpMethod().name().toString());
+
+        buildReturnType(functionImport, method, annotation);
+        buildParameter(functionImport, method);
+
+        return functionImport;
+      }
+      return null;
+    }
+
+    private void buildParameter(final FunctionImport functionImport, final Method method)
+        throws ODataJPAModelException {
+
+      Annotation[][] annotations = method.getParameterAnnotations();
+      Class<?>[] parameterTypes = method.getParameterTypes();
+      List<FunctionImportParameter> funcImpList = new ArrayList<FunctionImportParameter>();
+      JPAEdmMapping mapping = null;
+      int j = 0;
+      for (Annotation[] annotationArr : annotations) {
+        Class<?> parameterType = parameterTypes[j++];
+
+        for (Annotation element : annotationArr) {
+          if (element instanceof Parameter) {
+            Parameter annotation = (Parameter) element;
+            FunctionImportParameter functionImportParameter = new FunctionImportParameter();
+            if (annotation.name().equals("")) {
+              throw ODataJPAModelException.throwException(
+                  ODataJPAModelException.FUNC_PARAM_NAME_EXP
+                      .addContent(method
+                          .getDeclaringClass()
+                          .getName(), method
+                          .getName()), null);
+            } else {
+              functionImportParameter.setName(annotation.name());
+            }
+
+            functionImportParameter.setType(JPATypeConvertor
+                .convertToEdmSimpleType(parameterType, null));
+            functionImportParameter.setMode(annotation.mode()
+                .toString());
+
+            Facets facets = new Facets();
+            if (annotation.facets().maxLength() > 0) {
+              facets.setMaxLength(annotation.facets().maxLength());
+            }
+            if (annotation.facets().nullable() == false) {
+              facets.setNullable(false);
+            } else {
+              facets.setNullable(true);
+            }
+
+            if (annotation.facets().precision() > 0) {
+              facets.setPrecision(annotation.facets().precision());
+            }
+            if (annotation.facets().scale() >= 0) {
+              facets.setScale(annotation.facets().scale());
+            }
+
+            functionImportParameter.setFacets(facets);
+            mapping = new JPAEdmMappingImpl();
+            mapping.setJPAType(parameterType);
+            functionImportParameter.setMapping((Mapping) mapping);
+            funcImpList.add(functionImportParameter);
+          }
+        }
+      }
+      if (!funcImpList.isEmpty()) {
+        functionImport.setParameters(funcImpList);
+      }
+    }
+
+    private void buildReturnType(final FunctionImport functionImport,
+        final Method method,
+        final org.apache.olingo.odata2.api.annotation.edm.FunctionImport annotation)
+        throws ODataJPAModelException {
+      ReturnType returnType = annotation.returnType();
+      Multiplicity multiplicity = null;
+
+      if (returnType != ReturnType.NONE) {
+        org.apache.olingo.odata2.api.edm.provider.ReturnType functionReturnType = new org.apache.olingo.odata2.api.edm.provider.ReturnType();
+        multiplicity = annotation.multiplicity();
+
+        if (multiplicity == Multiplicity.MANY) {
+          functionReturnType.setMultiplicity(EdmMultiplicity.MANY);
+        } else {
+          functionReturnType.setMultiplicity(EdmMultiplicity.ONE);
+        }
+
+        if (returnType == ReturnType.ENTITY_TYPE) {
+          String entitySet = annotation.entitySet();
+          if (entitySet.equals("")) {
+            throw ODataJPAModelException
+                .throwException(
+                    ODataJPAModelException.FUNC_ENTITYSET_EXP,
+                    null);
+          }
+          functionImport.setEntitySet(entitySet);
+        }
+
+        Class<?> methodReturnType = method.getReturnType();
+        if (methodReturnType == null
+            || methodReturnType.getName().equals("void")) {
+          throw ODataJPAModelException.throwException(
+              ODataJPAModelException.FUNC_RETURN_TYPE_EXP
+                  .addContent(method.getDeclaringClass(),
+                      method.getName()), null);
+        }
+        switch (returnType) {
+        case ENTITY_TYPE:
+          EntityType edmEntityType = null;
+          if (multiplicity == Multiplicity.ONE) {
+            edmEntityType = jpaEdmEntityTypeView
+                .searchEdmEntityType(methodReturnType
+                    .getSimpleName());
+          } else if (multiplicity == Multiplicity.MANY) {
+            edmEntityType = jpaEdmEntityTypeView
+                .searchEdmEntityType(getReturnTypeSimpleName(method));
+          }
+
+          if (edmEntityType == null) {
+            throw ODataJPAModelException
+                .throwException(
+                    ODataJPAModelException.FUNC_RETURN_TYPE_ENTITY_NOT_FOUND
+                        .addContent(
+                            method.getDeclaringClass(),
+                            method.getName(),
+                            methodReturnType
+                                .getSimpleName()),
+                    null);
+          }
+          functionReturnType.setTypeName(JPAEdmNameBuilder.build(
+              schemaView, edmEntityType.getName()));
+          break;
+        case SCALAR:
+
+          EdmSimpleTypeKind edmSimpleTypeKind = JPATypeConvertor
+              .convertToEdmSimpleType(methodReturnType, null);
+          functionReturnType.setTypeName(edmSimpleTypeKind
+              .getFullQualifiedName());
+
+          break;
+        case COMPLEX_TYPE:
+          ComplexType complexType = null;
+          if (multiplicity == Multiplicity.ONE) {
+            complexType = jpaEdmComplexTypeView
+                .searchEdmComplexType(methodReturnType
+                    .getName());
+          } else if (multiplicity == Multiplicity.MANY) {
+            complexType = jpaEdmComplexTypeView
+                .searchEdmComplexType(getReturnTypeName(method));
+          }
+          if (complexType == null) {
+            throw ODataJPAModelException
+                .throwException(
+                    ODataJPAModelException.FUNC_RETURN_TYPE_ENTITY_NOT_FOUND
+                        .addContent(
+                            method.getDeclaringClass(),
+                            method.getName(),
+                            methodReturnType
+                                .getSimpleName()),
+                    null);
+          }
+          functionReturnType.setTypeName(JPAEdmNameBuilder.build(
+              schemaView, complexType.getName()));
+          break;
+        default:
+          break;
+        }
+        functionImport.setReturnType(functionReturnType);
+      }
+    }
+
+    private String getReturnTypeName(final Method method) {
+      try {
+        ParameterizedType pt = (ParameterizedType) method
+            .getGenericReturnType();
+        Type t = pt.getActualTypeArguments()[0];
+        return ((Class<?>) t).getName();
+      } catch (ClassCastException e) {
+        return method.getReturnType().getName();
+      }
+    }
+
+    private String getReturnTypeSimpleName(final Method method) {
+      try {
+        ParameterizedType pt = (ParameterizedType) method
+            .getGenericReturnType();
+        Type t = pt.getActualTypeArguments()[0];
+        return ((Class<?>) t).getSimpleName();
+      } catch (ClassCastException e) {
+        return method.getReturnType().getSimpleName();
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmKey.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmKey.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmKey.java
new file mode 100644
index 0000000..bc4a370
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmKey.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *        or more contributor license agreements.  See the NOTICE file
+ *        distributed with this work for additional information
+ *        regarding copyright ownership.  The ASF licenses this file
+ *        to you under the Apache License, Version 2.0 (the
+ *        "License"); you may not use this file except in compliance
+ *        with the License.  You may obtain a copy of the License at
+ * 
+ *          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.processor.core.jpa.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.Facets;
+import org.apache.olingo.odata2.api.edm.provider.Key;
+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.SimpleProperty;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmComplexTypeView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmKeyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmPropertyView;
+
+public class JPAEdmKey extends JPAEdmBaseViewImpl implements JPAEdmKeyView {
+
+  private JPAEdmPropertyView propertyView;
+  private JPAEdmComplexTypeView complexTypeView = null;
+  private boolean isBuildModeComplexType = false;
+  private Key key;
+
+  public JPAEdmKey(final JPAEdmProperty view) {
+    super(view);
+    propertyView = view;
+  }
+
+  public JPAEdmKey(final JPAEdmComplexTypeView complexTypeView,
+      final JPAEdmPropertyView propertyView) {
+    super(complexTypeView);
+    this.propertyView = propertyView;
+    this.complexTypeView = complexTypeView;
+    isBuildModeComplexType = true;
+  }
+
+  @Override
+  public JPAEdmBuilder getBuilder() {
+    if (builder == null) {
+      builder = new JPAEdmKeyBuider();
+    }
+
+    return builder;
+  }
+
+  @Override
+  public Key getEdmKey() {
+    return key;
+  }
+
+  private class JPAEdmKeyBuider implements JPAEdmBuilder {
+
+    @Override
+    public void build() throws ODataJPAModelException {
+
+      List<PropertyRef> propertyRefList = null;
+      if (key == null) {
+        key = new Key();
+      }
+
+      if (key.getKeys() == null) {
+        propertyRefList = new ArrayList<PropertyRef>();
+        key.setKeys(propertyRefList);
+      } else {
+        propertyRefList = key.getKeys();
+      }
+
+      if (isBuildModeComplexType) {
+        ComplexType complexType = complexTypeView
+            .searchEdmComplexType(propertyView
+                .getJPAAttribute().getJavaType().getName());
+        normalizeComplexKey(complexType, propertyRefList);
+      } else {
+        PropertyRef propertyRef = new PropertyRef();
+        propertyRef.setName(propertyView.getEdmSimpleProperty().getName());
+        Facets facets = (Facets) propertyView.getEdmSimpleProperty().getFacets();
+        if (facets == null) {
+          propertyView.getEdmSimpleProperty().setFacets(new Facets().setNullable(false));
+        } else {
+          facets.setNullable(false);
+        }
+        propertyRefList.add(propertyRef);
+      }
+
+    }
+
+    //TODO think how to stop the recursion if A includes B and B includes A!!!!!!
+    public void normalizeComplexKey(final ComplexType complexType, final List<PropertyRef> propertyRefList) {
+      for (Property property : complexType.getProperties()) {
+        try {
+
+          SimpleProperty simpleProperty = (SimpleProperty) property;
+          Facets facets = (Facets) simpleProperty.getFacets();
+          if (facets == null) {
+            simpleProperty.setFacets(new Facets().setNullable(false));
+          } else {
+            facets.setNullable(false);
+          }
+          PropertyRef propertyRef = new PropertyRef();
+          propertyRef.setName(simpleProperty.getName());
+          propertyRefList.add(propertyRef);
+
+        } catch (ClassCastException e) {
+          ComplexProperty complexProperty = (ComplexProperty) property;
+          normalizeComplexKey(complexTypeView.searchEdmComplexType(complexProperty.getType()), propertyRefList);
+        }
+
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmMappingImpl.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmMappingImpl.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmMappingImpl.java
new file mode 100644
index 0000000..cc40fad
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmMappingImpl.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.model;
+
+import org.apache.olingo.odata2.api.edm.provider.Mapping;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmMapping;
+
+public class JPAEdmMappingImpl extends Mapping implements JPAEdmMapping {
+
+  private String columnName = null;
+  private Class<?> type = null;
+
+  @Override
+  public void setJPAColumnName(final String name) {
+    columnName = name;
+
+  }
+
+  @Override
+  public String getJPAColumnName() {
+    return columnName;
+  }
+
+  @Override
+  public void setJPAType(final Class<?> type) {
+    this.type = type;
+
+  }
+
+  @Override
+  public Class<?> getJPAType() {
+    return type;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmModel.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmModel.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmModel.java
new file mode 100644
index 0000000..a307fa1
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmModel.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.model;
+
+import javax.persistence.metamodel.Metamodel;
+
+import org.apache.olingo.odata2.processor.api.jpa.ODataJPAContext;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmModelView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmSchemaView;
+
+public class JPAEdmModel extends JPAEdmBaseViewImpl implements JPAEdmModelView {
+
+  protected JPAEdmSchemaView schemaView;
+
+  public JPAEdmModel(final Metamodel metaModel, final String pUnitName) {
+    super(metaModel, pUnitName);
+  }
+
+  public JPAEdmModel(final ODataJPAContext ctx) {
+    super(ctx);
+  }
+
+  @Override
+  public JPAEdmSchemaView getEdmSchemaView() {
+    return schemaView;
+  }
+
+  @Override
+  public JPAEdmBuilder getBuilder() {
+    if (builder == null) {
+      builder = new JPAEdmModelBuilder();
+    }
+
+    return builder;
+  }
+
+  private class JPAEdmModelBuilder implements JPAEdmBuilder {
+
+    @Override
+    public void build() throws ODataJPAModelException, ODataJPARuntimeException {
+      schemaView = new JPAEdmSchema(JPAEdmModel.this);
+      schemaView.getBuilder().build();
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmNavigationProperty.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmNavigationProperty.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmNavigationProperty.java
new file mode 100644
index 0000000..d5e16f6
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmNavigationProperty.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.provider.NavigationProperty;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmAssociationView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmNavigationPropertyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmPropertyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmSchemaView;
+import org.apache.olingo.odata2.processor.core.jpa.access.model.JPAEdmNameBuilder;
+
+public class JPAEdmNavigationProperty extends JPAEdmBaseViewImpl implements
+    JPAEdmNavigationPropertyView {
+
+  private JPAEdmAssociationView associationView = null;
+  private NavigationProperty currentNavigationProperty = null;
+  private JPAEdmPropertyView propertyView = null;
+  private List<NavigationProperty> consistentNavigationProperties = null;
+  private int count;
+
+  public JPAEdmNavigationProperty(final JPAEdmAssociationView associationView,
+      final JPAEdmPropertyView propertyView, final int countNumber) {
+    super(associationView);
+    this.associationView = associationView;
+    this.propertyView = propertyView;
+    count = countNumber;
+    if (consistentNavigationProperties == null)
+    {
+      consistentNavigationProperties = new ArrayList<NavigationProperty>();
+    }
+  }
+
+  public JPAEdmNavigationProperty(final JPAEdmSchemaView schemaView) {
+    super(schemaView);
+    consistentNavigationProperties = new ArrayList<NavigationProperty>();
+
+  }
+
+  @Override
+  public JPAEdmBuilder getBuilder() {
+    if (builder == null) {
+      builder = new JPAEdmNavigationPropertyBuilder();
+    }
+
+    return builder;
+  }
+
+  private class JPAEdmNavigationPropertyBuilder implements JPAEdmBuilder {
+
+    @Override
+    public void build() throws ODataJPAModelException {
+
+      currentNavigationProperty = new NavigationProperty();
+      JPAEdmNameBuilder.build(associationView, propertyView,
+          JPAEdmNavigationProperty.this, count);
+      consistentNavigationProperties.add(currentNavigationProperty);
+    }
+
+  }
+
+  @Override
+  public NavigationProperty getEdmNavigationProperty() {
+    return currentNavigationProperty;
+  }
+
+  @Override
+  public List<NavigationProperty> getConsistentEdmNavigationProperties() {
+    return consistentNavigationProperties;
+  }
+
+  @Override
+  public void addJPAEdmNavigationPropertyView(
+      final JPAEdmNavigationPropertyView view) {
+    if (view != null && view.isConsistent()) {
+      currentNavigationProperty = view.getEdmNavigationProperty();
+      consistentNavigationProperties.add(currentNavigationProperty);
+
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmProperty.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmProperty.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmProperty.java
new file mode 100644
index 0000000..7d96345
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmProperty.java
@@ -0,0 +1,405 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.model;
+
+import java.lang.reflect.AnnotatedElement;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.Column;
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.Attribute.PersistentAttributeType;
+import javax.persistence.metamodel.SingularAttribute;
+
+import org.apache.olingo.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+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.Facets;
+import org.apache.olingo.odata2.api.edm.provider.Property;
+import org.apache.olingo.odata2.api.edm.provider.SimpleProperty;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmMappingModelAccess;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmAssociationEndView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmAssociationView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmComplexPropertyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmComplexTypeView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntityTypeView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmKeyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmNavigationPropertyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmPropertyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmReferentialConstraintView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmSchemaView;
+import org.apache.olingo.odata2.processor.core.jpa.access.model.JPAEdmNameBuilder;
+import org.apache.olingo.odata2.processor.core.jpa.access.model.JPATypeConvertor;
+
+public class JPAEdmProperty extends JPAEdmBaseViewImpl implements
+    JPAEdmPropertyView, JPAEdmComplexPropertyView {
+
+  private JPAEdmSchemaView schemaView;
+  private JPAEdmEntityTypeView entityTypeView;
+  private JPAEdmComplexTypeView complexTypeView;
+  private JPAEdmNavigationPropertyView navigationPropertyView = null;
+
+  private JPAEdmKeyView keyView;
+  private List<Property> properties;
+  private SimpleProperty currentSimpleProperty = null;
+  private ComplexProperty currentComplexProperty = null;
+  private Attribute<?, ?> currentAttribute;
+  private boolean isBuildModeComplexType;
+  private Map<String, Integer> associationCount;
+
+  public JPAEdmProperty(final JPAEdmSchemaView view) {
+    super(view);
+    schemaView = view;
+    entityTypeView = schemaView.getJPAEdmEntityContainerView()
+        .getJPAEdmEntitySetView().getJPAEdmEntityTypeView();
+    complexTypeView = schemaView.getJPAEdmComplexTypeView();
+    navigationPropertyView = new JPAEdmNavigationProperty(schemaView);
+    isBuildModeComplexType = false;
+    associationCount = new HashMap<String, Integer>();
+  }
+
+  public JPAEdmProperty(final JPAEdmSchemaView schemaView,
+      final JPAEdmComplexTypeView view) {
+    super(view);
+    this.schemaView = schemaView;
+    complexTypeView = view;
+    isBuildModeComplexType = true;
+  }
+
+  @Override
+  public JPAEdmBuilder getBuilder() {
+    if (builder == null) {
+      builder = new JPAEdmPropertyBuilder();
+    }
+
+    return builder;
+  }
+
+  @Override
+  public List<Property> getEdmPropertyList() {
+    return properties;
+  }
+
+  @Override
+  public JPAEdmKeyView getJPAEdmKeyView() {
+    return keyView;
+  }
+
+  @Override
+  public SimpleProperty getEdmSimpleProperty() {
+    return currentSimpleProperty;
+  }
+
+  @Override
+  public Attribute<?, ?> getJPAAttribute() {
+    return currentAttribute;
+  }
+
+  @Override
+  public ComplexProperty getEdmComplexProperty() {
+    return currentComplexProperty;
+  }
+
+  @Override
+  public JPAEdmNavigationPropertyView getJPAEdmNavigationPropertyView()
+  {
+    return navigationPropertyView;
+  }
+
+  private class JPAEdmPropertyBuilder implements JPAEdmBuilder {
+    /*
+     * 
+     * Each call to build method creates a new EDM Property List. 
+     * The Property List can be created either by an Entity type or
+     * ComplexType. The flag isBuildModeComplexType tells if the
+     * Properties are built for complex type or for Entity Type.
+     * 
+     * While Building Properties Associations are built. However
+     * the associations thus built does not contain Referential
+     * constraint. Associations thus built only contains
+     * information about Referential constraints. Adding of
+     * referential constraints to Associations is the taken care
+     * by Schema.
+     * 
+     * Building Properties is divided into four parts
+     * 	A) Building Simple Properties
+     * 	B) Building Complex Properties
+     * 	C) Building Associations
+     * 	D) Building Navigation Properties
+     *  
+     * ************************************************************
+     * 					Build EDM Schema - STEPS
+     * ************************************************************
+     * A) 	Building Simple Properties:
+     * 
+     * 	1) 	Fetch JPA Attribute List from 
+     * 			A) Complex Type
+     * 			B) Entity Type
+     * 	  	depending on isBuildModeComplexType.
+     * B)	Building Complex Properties
+     * C)	Building Associations
+     * D)	Building Navigation Properties
+    	
+     * ************************************************************
+     * 					Build EDM Schema - STEPS
+     * ************************************************************
+     *
+     */
+    @Override
+    public void build() throws ODataJPAModelException, ODataJPARuntimeException {
+
+      JPAEdmBuilder keyViewBuilder = null;
+
+      properties = new ArrayList<Property>();
+
+      List<Attribute<?, ?>> jpaAttributes = null;
+      String currentEntityName = null;
+      String targetEntityName = null;
+      String entityTypeName = null;
+      if (isBuildModeComplexType) {
+        jpaAttributes = sortInAscendingOrder(complexTypeView.getJPAEmbeddableType()
+            .getAttributes());
+        entityTypeName = complexTypeView.getJPAEmbeddableType().getJavaType()
+            .getSimpleName();
+      } else {
+        jpaAttributes = sortInAscendingOrder(entityTypeView.getJPAEntityType()
+            .getAttributes());
+        entityTypeName = entityTypeView.getJPAEntityType().getName();
+      }
+
+      for (Object jpaAttribute : jpaAttributes) {
+        currentAttribute = (Attribute<?, ?>) jpaAttribute;
+
+        // Check for need to Exclude 
+        if (isExcluded((JPAEdmPropertyView) JPAEdmProperty.this, entityTypeName, currentAttribute.getName())) {
+          continue;
+        }
+
+        PersistentAttributeType attributeType = currentAttribute
+            .getPersistentAttributeType();
+
+        switch (attributeType) {
+        case BASIC:
+
+          currentSimpleProperty = new SimpleProperty();
+          JPAEdmNameBuilder
+              .build((JPAEdmPropertyView) JPAEdmProperty.this, isBuildModeComplexType);
+
+          EdmSimpleTypeKind simpleTypeKind = JPATypeConvertor
+              .convertToEdmSimpleType(currentAttribute
+                  .getJavaType(), currentAttribute);
+
+          currentSimpleProperty.setType(simpleTypeKind);
+          currentSimpleProperty
+              .setFacets(setFacets(currentAttribute));
+
+          properties.add(currentSimpleProperty);
+
+          if (((SingularAttribute<?, ?>) currentAttribute).isId()) {
+            if (keyView == null) {
+              keyView = new JPAEdmKey(JPAEdmProperty.this);
+              keyViewBuilder = keyView.getBuilder();
+            }
+
+            keyViewBuilder.build();
+          }
+
+          break;
+        case EMBEDDED:
+          ComplexType complexType = complexTypeView
+              .searchEdmComplexType(currentAttribute.getJavaType().getName());
+
+          if (complexType == null) {
+            JPAEdmComplexTypeView complexTypeViewLocal = new JPAEdmComplexType(
+                schemaView, currentAttribute);
+            complexTypeViewLocal.getBuilder().build();
+            complexType = complexTypeViewLocal.getEdmComplexType();
+            complexTypeView.addJPAEdmCompleTypeView(complexTypeViewLocal);
+
+          }
+
+          if (isBuildModeComplexType == false
+              && entityTypeView.getJPAEntityType().getIdType()
+                  .getJavaType()
+                  .equals(currentAttribute.getJavaType())) {
+
+            if (keyView == null) {
+              keyView = new JPAEdmKey(complexTypeView,
+                  JPAEdmProperty.this);
+            }
+            keyView.getBuilder().build();
+            complexTypeView.expandEdmComplexType(complexType, properties, currentAttribute.getName());
+          }
+          else {
+            currentComplexProperty = new ComplexProperty();
+            if (isBuildModeComplexType) {
+              JPAEdmNameBuilder
+                  .build((JPAEdmComplexPropertyView) JPAEdmProperty.this,
+                      complexTypeView.getJPAEmbeddableType().getJavaType().getSimpleName());
+            } else {
+              JPAEdmNameBuilder
+                  .build((JPAEdmComplexPropertyView) JPAEdmProperty.this,
+                      JPAEdmProperty.this);
+            }
+            currentComplexProperty.setType(new FullQualifiedName(
+                schemaView.getEdmSchema().getNamespace(),
+                complexType.getName()));
+            currentComplexProperty
+                .setFacets(setFacets(currentAttribute));
+            properties.add(currentComplexProperty);
+            List<String> nonKeyComplexTypes = schemaView.getNonKeyComplexTypeList();
+            if (!nonKeyComplexTypes.contains(currentComplexProperty.getType().getName()))
+            {
+              schemaView.addNonKeyComplexName(currentComplexProperty.getType().getName());
+            }
+          }
+
+          break;
+        case MANY_TO_MANY:
+        case ONE_TO_MANY:
+        case ONE_TO_ONE:
+        case MANY_TO_ONE:
+
+          JPAEdmAssociationEndView associationEndView = new JPAEdmAssociationEnd(entityTypeView, JPAEdmProperty.this);
+          associationEndView.getBuilder().build();
+          JPAEdmAssociationView associationView = schemaView.getJPAEdmAssociationView();
+          if (associationView.searchAssociation(associationEndView) == null) {
+            int count = associationView.getNumberOfAssociationsWithSimilarEndPoints(associationEndView);
+            JPAEdmAssociationView associationViewLocal = new JPAEdmAssociation(associationEndView, entityTypeView, JPAEdmProperty.this, count);
+            associationViewLocal.getBuilder().build();
+            associationView.addJPAEdmAssociationView(associationViewLocal, associationEndView);
+          }
+
+          JPAEdmReferentialConstraintView refConstraintView = new JPAEdmReferentialConstraint(
+              associationView, entityTypeView, JPAEdmProperty.this);
+          refConstraintView.getBuilder().build();
+
+          if (refConstraintView.isExists()) {
+            associationView.addJPAEdmRefConstraintView(refConstraintView);
+          }
+
+          if (navigationPropertyView == null)
+          {
+            navigationPropertyView = new JPAEdmNavigationProperty(schemaView);
+          }
+          currentEntityName = entityTypeView.getJPAEntityType().getName();
+          targetEntityName = currentAttribute.getJavaType().getSimpleName();
+          Integer sequenceNumber = associationCount.get(currentEntityName + targetEntityName);
+          if (sequenceNumber == null) {
+            sequenceNumber = new Integer(1);
+          } else {
+            sequenceNumber = new Integer(sequenceNumber.intValue() + 1);
+          }
+          associationCount.put(currentEntityName + targetEntityName, sequenceNumber);
+          JPAEdmNavigationPropertyView localNavigationPropertyView = new JPAEdmNavigationProperty(associationView, JPAEdmProperty.this, sequenceNumber.intValue());
+          localNavigationPropertyView.getBuilder().build();
+          navigationPropertyView.addJPAEdmNavigationPropertyView(localNavigationPropertyView);
+          break;
+        default:
+          break;
+        }
+      }
+
+    }
+
+    @SuppressWarnings("rawtypes")
+    private List<Attribute<?, ?>> sortInAscendingOrder(final Set<?> jpaAttributes) {
+      List<Attribute<?, ?>> jpaAttributeList = new ArrayList<Attribute<?, ?>>();
+      Iterator itr = null;
+      Attribute<?, ?> smallestJpaAttribute;
+      Attribute<?, ?> currentJpaAttribute;
+      while (!jpaAttributes.isEmpty()) {
+        itr = jpaAttributes.iterator();
+        smallestJpaAttribute = (Attribute<?, ?>) itr.next();
+        while (itr.hasNext()) {
+          currentJpaAttribute = (Attribute<?, ?>) itr.next();
+          if (smallestJpaAttribute.getName().compareTo(currentJpaAttribute.getName()) > 0) {
+            smallestJpaAttribute = currentJpaAttribute;
+          }
+        }
+        jpaAttributeList.add(smallestJpaAttribute);
+        jpaAttributes.remove(smallestJpaAttribute);
+      }
+      return jpaAttributeList;
+    }
+
+    private EdmFacets setFacets(final Attribute<?, ?> jpaAttribute)
+        throws ODataJPAModelException, ODataJPARuntimeException {
+
+      Facets facets = new Facets();
+      if (jpaAttribute.getJavaMember() instanceof AnnotatedElement) {
+        Column column = ((AnnotatedElement) jpaAttribute
+            .getJavaMember()).getAnnotation(Column.class);
+        if (column != null) {
+          EdmSimpleTypeKind attrEmdType = JPATypeConvertor
+              .convertToEdmSimpleType(jpaAttribute.getJavaType(), jpaAttribute);
+          if (column.nullable()) {
+            facets.setNullable(true);
+          } else {
+            facets.setNullable(false);
+          }
+          if (column.length() != 0
+              && attrEmdType.equals(EdmSimpleTypeKind.String)) {
+            facets.setMaxLength(column.length());
+          }
+          if (column.precision() != 0
+              && attrEmdType.equals(EdmSimpleTypeKind.Double)) {
+            facets.setPrecision(column.precision());
+          }
+        }
+        return facets;
+      }
+      return facets;
+    }
+  }
+
+  @Override
+  public JPAEdmEntityTypeView getJPAEdmEntityTypeView() {
+    return entityTypeView;
+  }
+
+  @Override
+  public JPAEdmComplexTypeView getJPAEdmComplexTypeView() {
+    return complexTypeView;
+  }
+
+  private boolean isExcluded(final JPAEdmPropertyView jpaEdmPropertyView, final String jpaEntityTypeName, final String jpaAttributeName) {
+    JPAEdmMappingModelAccess mappingModelAccess = jpaEdmPropertyView
+        .getJPAEdmMappingModelAccess();
+    boolean isExcluded = false;
+    if (mappingModelAccess != null && mappingModelAccess.isMappingModelExists()) {
+      // Exclusion of a simple property in a complex type
+      if (isBuildModeComplexType && mappingModelAccess.checkExclusionOfJPAEmbeddableAttributeType(jpaEntityTypeName, jpaAttributeName)
+          // Exclusion of a simple property of an Entity Type
+          || (!isBuildModeComplexType && mappingModelAccess.checkExclusionOfJPAAttributeType(jpaEntityTypeName, jpaAttributeName))) {
+        isExcluded = true;
+      }
+    }
+    return isExcluded;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmReferentialConstraint.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmReferentialConstraint.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmReferentialConstraint.java
new file mode 100644
index 0000000..df39fc3
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmReferentialConstraint.java
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.model;
+
+import org.apache.olingo.odata2.api.edm.provider.ReferentialConstraint;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmAssociationView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntityTypeView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmPropertyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmReferentialConstraintRoleView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmReferentialConstraintRoleView.RoleType;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmReferentialConstraintView;
+
+public class JPAEdmReferentialConstraint extends JPAEdmBaseViewImpl implements
+    JPAEdmReferentialConstraintView {
+
+  private JPAEdmRefConstraintBuilder builder = null;
+
+  private boolean exists = false;
+  private boolean firstBuild = true;
+
+  private JPAEdmAssociationView associationView;
+  private JPAEdmPropertyView propertyView;
+  private JPAEdmEntityTypeView entityTypeView;
+
+  private ReferentialConstraint referentialConstraint;
+
+  private JPAEdmReferentialConstraintRoleView principalRoleView;
+  private JPAEdmReferentialConstraintRoleView dependentRoleView;
+
+  private String relationShipName;
+
+  public JPAEdmReferentialConstraint(final JPAEdmAssociationView associationView,
+      final JPAEdmEntityTypeView entityTypeView, final JPAEdmPropertyView propertyView) {
+    super(associationView);
+    this.associationView = associationView;
+    this.propertyView = propertyView;
+    this.entityTypeView = entityTypeView;
+
+    relationShipName = associationView.getEdmAssociation().getName();
+  }
+
+  @Override
+  public JPAEdmBuilder getBuilder() {
+    if (builder == null) {
+      builder = new JPAEdmRefConstraintBuilder();
+    }
+
+    return builder;
+  }
+
+  @Override
+  public ReferentialConstraint getEdmReferentialConstraint() {
+    return referentialConstraint;
+  }
+
+  @Override
+  public boolean isExists() {
+    return exists;
+  }
+
+  @Override
+  public String getEdmRelationShipName() {
+    return relationShipName;
+  }
+
+  private class JPAEdmRefConstraintBuilder implements JPAEdmBuilder {
+    /*
+     * Check if Ref Constraint was already Built. If Ref constraint was
+     * already built consistently then do not build referential constraint.
+     * 
+     * For Ref Constraint to be consistently built Principal and Dependent
+     * roles must be consistently built. If Principal or Dependent roles are
+     * not consistently built then try building them again.
+     * 
+     * The Principal and Dependent roles could be have been built
+     * inconsistently if the required EDM Entity Types or EDM properties are
+     * yet to be built. In such cases rebuilding these roles would make them
+     * consistent.
+     */
+    @Override
+    public void build() throws ODataJPAModelException, ODataJPARuntimeException {
+
+      if (firstBuild) {
+        firstBuild();
+      } else {
+        if (exists && !firstBuild
+            && principalRoleView.isConsistent() == false) {
+          principalRoleView.getBuilder().build();
+        }
+
+        if (exists && !firstBuild
+            && dependentRoleView.isConsistent() == false) {
+          dependentRoleView.getBuilder().build();
+        }
+      }
+
+      if (principalRoleView.isConsistent()) {
+        referentialConstraint.setPrincipal(principalRoleView
+            .getEdmReferentialConstraintRole());
+      }
+
+      if (dependentRoleView.isConsistent()) {
+        referentialConstraint.setDependent(dependentRoleView
+            .getEdmReferentialConstraintRole());
+      }
+
+      exists = principalRoleView.isExists()
+          & dependentRoleView.isExists();
+
+      isConsistent = principalRoleView.isConsistent()
+          & dependentRoleView.isConsistent();
+
+    }
+
+    private void firstBuild() throws ODataJPAModelException, ODataJPARuntimeException {
+      firstBuild = false;
+      if (principalRoleView == null && dependentRoleView == null) {
+
+        principalRoleView = new JPAEdmReferentialConstraintRole(
+            RoleType.PRINCIPAL, entityTypeView, propertyView,
+            associationView);
+        principalRoleView.getBuilder().build();
+
+        dependentRoleView = new JPAEdmReferentialConstraintRole(
+            RoleType.DEPENDENT, entityTypeView, propertyView,
+            associationView);
+        dependentRoleView.getBuilder().build();
+
+        if (referentialConstraint == null) {
+          referentialConstraint = new ReferentialConstraint();
+        }
+      }
+
+    }
+  }
+
+}