You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2013/12/18 10:12:28 UTC

[30/37] [OLINGO-82] Renamed the project folder name to odata2-jpa-processor

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/1b479e6c/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmBaseViewImpl.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmBaseViewImpl.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmBaseViewImpl.java
new file mode 100644
index 0000000..0798487
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmBaseViewImpl.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * 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 boolean skipDefaultNaming = false;
+  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();
+    skipDefaultNaming = view.isDefaultNamingSkipped();
+  }
+
+  public JPAEdmBaseViewImpl(final ODataJPAContext context) {
+    pUnitName = context.getPersistenceUnitName();
+    metaModel = context.getEntityManagerFactory().getMetamodel();
+    jpaEdmMappingModelAccess =
+        ODataJPAFactory.createFactory().getJPAAccessFactory().getJPAEdmMappingModelAccess(context);
+    jpaEdmExtension = context.getJPAEdmExtension();
+    jpaEdmMappingModelAccess.loadMappingModel();
+    skipDefaultNaming = !context.getDefaultNaming();
+  }
+
+  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;
+  }
+
+  @Override
+  public boolean isDefaultNamingSkipped() {
+    return skipDefaultNaming;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/1b479e6c/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmComplexType.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmComplexType.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmComplexType.java
new file mode 100644
index 0000000..ad25a1b
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmComplexType.java
@@ -0,0 +1,254 @@
+/*******************************************************************************
+ * 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());
+        newMapping.setJPAType(oldMapping.getJPAType());
+        newSimpleProperty.setMapping(newMapping);
+        expandedList.add(newSimpleProperty);
+      } catch (ClassCastException e) {
+        ComplexProperty complexProperty = (ComplexProperty) property;
+        String name = embeddablePropertyName + "." + 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/1b479e6c/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntityContainer.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntityContainer.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntityContainer.java
new file mode 100644
index 0000000..fee40c2
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntityContainer.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * 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/1b479e6c/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntitySet.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntitySet.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntitySet.java
new file mode 100644
index 0000000..9e5248f
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntitySet.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * 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/1b479e6c/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntityType.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntityType.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntityType.java
new file mode 100644
index 0000000..5864a1c
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmEntityType.java
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * 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/1b479e6c/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmFacets.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmFacets.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmFacets.java
new file mode 100644
index 0000000..61f984f
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmFacets.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * 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 javax.persistence.Column;
+import javax.persistence.metamodel.Attribute;
+
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.edm.provider.Facets;
+import org.apache.olingo.odata2.api.edm.provider.SimpleProperty;
+
+public class JPAEdmFacets {
+  public static void setFacets(final Attribute<?, ?> jpaAttribute, final SimpleProperty edmProperty) {
+    EdmSimpleTypeKind edmTypeKind = edmProperty.getType();
+    Facets facets = new Facets();
+    edmProperty.setFacets(facets);
+
+    Column column = null;
+    if (jpaAttribute.getJavaMember() instanceof AnnotatedElement) {
+      column = ((AnnotatedElement) jpaAttribute
+          .getJavaMember()).getAnnotation(Column.class);
+    }
+
+    if (column == null) {
+      return;
+    }
+
+    setNullable(column, edmProperty);
+
+    switch (edmTypeKind) {
+    case Binary:
+      setMaxLength(column, edmProperty);
+      break;
+    case DateTime:
+      setPrecision(column, edmProperty);
+      break;
+    case DateTimeOffset:
+      setPrecision(column, edmProperty);
+      break;
+    case Time:
+      setPrecision(column, edmProperty);
+      break;
+    case Decimal:
+      setPrecision(column, edmProperty);
+      setScale(column, edmProperty);
+      break;
+    case String:
+      setMaxLength(column, edmProperty);
+      break;
+    default:
+      break;
+    }
+  }
+
+  private static void setNullable(final Column column, final SimpleProperty edmProperty) {
+    ((Facets) edmProperty.getFacets()).setNullable(column.nullable());
+  }
+
+  private static void setMaxLength(final Column column, final SimpleProperty edmProperty) {
+    if (column.length() > 0) {
+      ((Facets) edmProperty.getFacets()).setMaxLength(column.length());
+    }
+  }
+
+  private static void setPrecision(final Column column, final SimpleProperty edmProperty) {
+    if (column.precision() > 0) {
+      ((Facets) edmProperty.getFacets()).setPrecision(column.precision());
+    }
+  }
+
+  private static void setScale(final Column column, final SimpleProperty edmProperty) {
+    if (column.scale() > 0) {
+      ((Facets) edmProperty.getFacets()).setScale(column.scale());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/1b479e6c/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmFunctionImport.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmFunctionImport.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmFunctionImport.java
new file mode 100644
index 0000000..b64f61c
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmFunctionImport.java
@@ -0,0 +1,331 @@
+/*******************************************************************************
+ * 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.EdmFunctionImport;
+import org.apache.olingo.odata2.api.annotation.edm.EdmFunctionImport.ReturnType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmFunctionImportParameter;
+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;
+    @SuppressWarnings("deprecation")
+    private _JPAEdmFunctionImportBuilder builderDeprecated = new _JPAEdmFunctionImportBuilder();
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void build() throws ODataJPAModelException, ODataJPARuntimeException {
+
+      HashMap<Class<?>, String[]> customOperations = schemaView.getRegisteredOperations();
+
+      jpaEdmEntityTypeView =
+          schemaView.getJPAEdmEntityContainerView().getJPAEdmEntitySetView().getJPAEdmEntityTypeView();
+      jpaEdmComplexTypeView = schemaView.getJPAEdmComplexTypeView();
+
+      if (customOperations != null) {
+        // Initialize deprecated Builder
+        builderDeprecated.setJPAEdmComplexTypeView(jpaEdmComplexTypeView);
+        builderDeprecated.setJPAEdmEntityTypeView(jpaEdmEntityTypeView);
+        builderDeprecated.setSchemaView(schemaView);
+
+        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);
+            }
+          }
+        }
+      }
+    }
+
+    @SuppressWarnings("deprecation")
+    private FunctionImport buildFunctionImport(final Method method) throws ODataJPAModelException {
+
+      EdmFunctionImport edmAnnotationFunctionImport = method.getAnnotation(EdmFunctionImport.class);
+      if (edmAnnotationFunctionImport != null && edmAnnotationFunctionImport.returnType() != null) {
+        return buildEdmFunctionImport(method, edmAnnotationFunctionImport);
+      }
+
+      org.apache.olingo.odata2.api.annotation.edm.FunctionImport annotation =
+          method.getAnnotation(org.apache.olingo.odata2.api.annotation.edm.FunctionImport.class);
+
+      if (annotation != null) {
+        FunctionImport functionImport = builderDeprecated.buildFunctionImport(method, annotation);
+
+        return functionImport;
+      }
+      return null;
+    }
+
+    private FunctionImport buildEdmFunctionImport(final Method method,
+        final EdmFunctionImport edmAnnotationFunctionImport)
+        throws ODataJPAModelException {
+      if (edmAnnotationFunctionImport != null && edmAnnotationFunctionImport.returnType() != null) {
+        FunctionImport functionImport = new FunctionImport();
+
+        if (edmAnnotationFunctionImport.name().equals("")) {
+          functionImport.setName(method.getName());
+        } else {
+          functionImport.setName(edmAnnotationFunctionImport.name());
+        }
+
+        JPAEdmMapping mapping = new JPAEdmMappingImpl();
+        ((Mapping) mapping).setInternalName(method.getName());
+        mapping.setJPAType(method.getDeclaringClass());
+        functionImport.setMapping((Mapping) mapping);
+
+        functionImport.setHttpMethod(edmAnnotationFunctionImport.httpMethod().name().toString());
+
+        buildEdmReturnType(functionImport, method, edmAnnotationFunctionImport);
+        buildEdmParameter(functionImport, method);
+
+        return functionImport;
+      }
+      return null;
+    }
+
+    private void buildEdmParameter(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 EdmFunctionImportParameter) {
+            EdmFunctionImportParameter annotation = (EdmFunctionImportParameter) 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));
+
+            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 buildEdmReturnType(final FunctionImport functionImport, final Method method,
+        final EdmFunctionImport edmAnnotationFunctionImport) throws ODataJPAModelException {
+      ReturnType returnType = edmAnnotationFunctionImport.returnType();
+
+      if (returnType != null) {
+        org.apache.olingo.odata2.api.edm.provider.ReturnType functionReturnType =
+            new org.apache.olingo.odata2.api.edm.provider.ReturnType();
+
+        if (returnType.isCollection()) {
+          functionReturnType.setMultiplicity(EdmMultiplicity.MANY);
+        } else {
+          functionReturnType.setMultiplicity(EdmMultiplicity.ONE);
+        }
+
+        if (returnType.type() == ReturnType.Type.ENTITY) {
+          String entitySet = edmAnnotationFunctionImport.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.type()) {
+        case ENTITY:
+          EntityType edmEntityType = null;
+          if (returnType.isCollection() == false) {
+            edmEntityType = jpaEdmEntityTypeView.searchEdmEntityType(methodReturnType.getSimpleName());
+          } else {
+            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 SIMPLE:
+          EdmSimpleTypeKind edmSimpleTypeKind = JPATypeConvertor.convertToEdmSimpleType(methodReturnType, null);
+          functionReturnType.setTypeName(edmSimpleTypeKind.getFullQualifiedName());
+
+          break;
+        case COMPLEX:
+          ComplexType complexType = null;
+          if (returnType.isCollection() == false) {
+            complexType = jpaEdmComplexTypeView.searchEdmComplexType(methodReturnType.getName());
+          } else {
+            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/1b479e6c/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmKey.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmKey.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmKey.java
new file mode 100644
index 0000000..15cd26e
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmKey.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * 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/1b479e6c/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmMappingImpl.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmMappingImpl.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmMappingImpl.java
new file mode 100644
index 0000000..99d9f5f
--- /dev/null
+++ b/odata2-jpa-processor/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/1b479e6c/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmModel.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmModel.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmModel.java
new file mode 100644
index 0000000..fac5614
--- /dev/null
+++ b/odata2-jpa-processor/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/1b479e6c/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmNavigationProperty.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmNavigationProperty.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmNavigationProperty.java
new file mode 100644
index 0000000..4757c9a
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmNavigationProperty.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * 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, skipDefaultNaming, 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/1b479e6c/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmProperty.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmProperty.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmProperty.java
new file mode 100644
index 0000000..b34a71d
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmProperty.java
@@ -0,0 +1,378 @@
+/*******************************************************************************
+ * 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.Map;
+import java.util.Set;
+
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.Attribute.PersistentAttributeType;
+import javax.persistence.metamodel.PluralAttribute;
+import javax.persistence.metamodel.SingularAttribute;
+
+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.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, skipDefaultNaming);
+
+          EdmSimpleTypeKind simpleTypeKind = JPATypeConvertor
+              .convertToEdmSimpleType(currentAttribute
+                  .getJavaType(), currentAttribute);
+
+          currentSimpleProperty.setType(simpleTypeKind);
+          JPAEdmFacets.setFacets(currentAttribute, currentSimpleProperty);
+
+          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, skipDefaultNaming);
+            }
+            currentComplexProperty.setType(new FullQualifiedName(
+                schemaView.getEdmSchema().getNamespace(),
+                complexType.getName()));
+
+            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();
+
+          if (currentAttribute.isCollection()) {
+            targetEntityName = ((PluralAttribute<?, ?, ?>) currentAttribute).getElementType().getJavaType()
+                .getSimpleName();
+          } else {
+            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;
+    }
+  }
+
+  @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;
+  }
+}