You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by tb...@apache.org on 2014/01/02 13:47:18 UTC

[31/47] [OLINGO-99] Re-factor Package Names. Following are the changes

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/63b621a8/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmFunctionImport.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmFunctionImport.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmFunctionImport.java
new file mode 100644
index 0000000..d35eae0
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmFunctionImport.java
@@ -0,0 +1,349 @@
+/*******************************************************************************
+ * 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.jpa.processor.core.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.jpa.processor.api.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmComplexTypeView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmEntityTypeView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmFunctionImportView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmSchemaView;
+import org.apache.olingo.odata2.jpa.processor.core.access.model.JPAEdmNameBuilder;
+import org.apache.olingo.odata2.jpa.processor.core.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:
+          String embeddableTypeName = null;
+          ComplexType complexType = null;
+          boolean exists = false;
+
+          if (returnType.isCollection() == false) {
+            embeddableTypeName = methodReturnType.getName();
+          } else {
+            embeddableTypeName = getReturnTypeName(method);
+          }
+
+          complexType = jpaEdmComplexTypeView.searchEdmComplexType(embeddableTypeName);
+
+          if (complexType == null) {// This could occure of non JPA Embeddable Types : Extension Scenario
+            List<ComplexType> complexTypeList = schemaView.getEdmSchema().getComplexTypes();
+            String[] complexTypeNameParts = embeddableTypeName.split("\\.");
+            String complexTypeName = complexTypeNameParts[complexTypeNameParts.length - 1];
+            for (ComplexType complexType1 : complexTypeList) {
+              if (complexType1.getName().equals(complexTypeName)) {
+                complexType = complexType1;
+                exists = true;
+                break;
+              }
+            }
+            if (exists == false) {
+              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/63b621a8/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmKey.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmKey.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmKey.java
new file mode 100644
index 0000000..69b6d07
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/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.jpa.processor.core.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.jpa.processor.api.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmComplexTypeView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmKeyView;
+import org.apache.olingo.odata2.jpa.processor.api.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/63b621a8/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmMappingImpl.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmMappingImpl.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmMappingImpl.java
new file mode 100644
index 0000000..f930d20
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/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.jpa.processor.core.model;
+
+import org.apache.olingo.odata2.api.edm.provider.Mapping;
+import org.apache.olingo.odata2.jpa.processor.api.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/63b621a8/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmModel.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmModel.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmModel.java
new file mode 100644
index 0000000..966bdd0
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/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.jpa.processor.core.model;
+
+import javax.persistence.metamodel.Metamodel;
+
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
+import org.apache.olingo.odata2.jpa.processor.api.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmModelView;
+import org.apache.olingo.odata2.jpa.processor.api.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/63b621a8/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmNavigationProperty.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmNavigationProperty.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmNavigationProperty.java
new file mode 100644
index 0000000..b1b06f4
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/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.jpa.processor.core.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.provider.NavigationProperty;
+import org.apache.olingo.odata2.jpa.processor.api.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmAssociationView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmNavigationPropertyView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmPropertyView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmSchemaView;
+import org.apache.olingo.odata2.jpa.processor.core.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/63b621a8/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmProperty.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmProperty.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmProperty.java
new file mode 100644
index 0000000..0923176
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmProperty.java
@@ -0,0 +1,377 @@
+/*******************************************************************************
+ * 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.jpa.processor.core.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.jpa.processor.api.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.jpa.processor.api.access.JPAEdmMappingModelAccess;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmAssociationEndView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmAssociationView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmComplexPropertyView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmComplexTypeView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmEntityTypeView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmKeyView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmNavigationPropertyView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmPropertyView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmReferentialConstraintView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmSchemaView;
+import org.apache.olingo.odata2.jpa.processor.core.access.model.JPAEdmNameBuilder;
+import org.apache.olingo.odata2.jpa.processor.core.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);
+            if (!complexTypeView.isReferencedInKey(currentComplexProperty.getType().getName()))
+            {
+              complexTypeView.setReferencedInKey(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;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/63b621a8/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmReferentialConstraint.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmReferentialConstraint.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmReferentialConstraint.java
new file mode 100644
index 0000000..cd80e70
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmReferentialConstraint.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * 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.jpa.processor.core.model;
+
+import org.apache.olingo.odata2.api.edm.provider.ReferentialConstraint;
+import org.apache.olingo.odata2.jpa.processor.api.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmAssociationView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmEntityTypeView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmPropertyView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmReferentialConstraintRoleView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmReferentialConstraintView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmReferentialConstraintRoleView.RoleType;
+
+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();
+        }
+      }
+
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/63b621a8/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmReferentialConstraintRole.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmReferentialConstraintRole.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmReferentialConstraintRole.java
new file mode 100644
index 0000000..6358774
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmReferentialConstraintRole.java
@@ -0,0 +1,258 @@
+/*******************************************************************************
+ * 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.jpa.processor.core.model;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinColumns;
+import javax.persistence.metamodel.Attribute;
+
+import org.apache.olingo.odata2.api.edm.provider.Association;
+import org.apache.olingo.odata2.api.edm.provider.AssociationEnd;
+import org.apache.olingo.odata2.api.edm.provider.EntityType;
+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.ReferentialConstraintRole;
+import org.apache.olingo.odata2.jpa.processor.api.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmAssociationView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmEntityTypeView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmPropertyView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmReferentialConstraintRoleView;
+
+public class JPAEdmReferentialConstraintRole extends JPAEdmBaseViewImpl implements JPAEdmReferentialConstraintRoleView {
+  /*
+   * Static Buffer
+   */
+  private static Attribute<?, ?> bufferedJPAAttribute = null;
+  private static ArrayList<JoinColumn> bufferedJoinColumns = new ArrayList<JoinColumn>();
+  /*
+   * Static Buffer
+   */
+
+  private boolean firstBuild = true;
+
+  private JPAEdmEntityTypeView entityTypeView;
+  private JPAEdmReferentialConstraintRoleView.RoleType roleType;
+
+  private Attribute<?, ?> jpaAttribute;
+  private ArrayList<String> jpaColumnNames;
+  private Association association;
+
+  private boolean roleExists = false;
+
+  private JPAEdmRefConstraintRoleBuilder builder;
+  private ReferentialConstraintRole currentRole;
+
+  public JPAEdmReferentialConstraintRole(final JPAEdmReferentialConstraintRoleView.RoleType roleType,
+      final JPAEdmEntityTypeView entityTypeView, final JPAEdmPropertyView propertyView,
+      final JPAEdmAssociationView associationView) {
+
+    super(entityTypeView);
+    this.entityTypeView = entityTypeView;
+    this.roleType = roleType;
+
+    jpaAttribute = propertyView.getJPAAttribute();
+    association = associationView.getEdmAssociation();
+
+  }
+
+  @Override
+  public boolean isExists() {
+    return roleExists;
+
+  }
+
+  @Override
+  public JPAEdmBuilder getBuilder() {
+    if (builder == null) {
+      builder = new JPAEdmRefConstraintRoleBuilder();
+    }
+
+    return builder;
+  }
+
+  @Override
+  public RoleType getRoleType() {
+    return roleType;
+  }
+
+  @Override
+  public ReferentialConstraintRole getEdmReferentialConstraintRole() {
+    return currentRole;
+  }
+
+  @Override
+  public String getJPAColumnName() {
+    return null;
+  }
+
+  @Override
+  public String getEdmEntityTypeName() {
+    return null;
+  }
+
+  @Override
+  public String getEdmAssociationName() {
+    return null;
+  }
+
+  private class JPAEdmRefConstraintRoleBuilder implements JPAEdmBuilder {
+
+    @Override
+    public void build() throws ODataJPAModelException {
+      if (firstBuild) {
+        firstBuild();
+      } else if (roleExists) {
+        try {
+          buildRole();
+        } catch (SecurityException e) {
+          throw ODataJPAModelException.throwException(ODataJPAModelException.GENERAL.addContent(e.getMessage()), e);
+        } catch (NoSuchFieldException e) {
+          throw ODataJPAModelException.throwException(ODataJPAModelException.GENERAL.addContent(e.getMessage()), e);
+        }
+      }
+
+    }
+
+    private void firstBuild() {
+      firstBuild = false;
+      isConsistent = false;
+
+      extractJoinColumns();
+
+      if (!roleExists) {
+        return;
+      }
+
+      jpaColumnNames = new ArrayList<String>();
+
+      for (JoinColumn joinColumn : bufferedJoinColumns) {
+        if (roleType == RoleType.PRINCIPAL) {
+          jpaColumnNames.add(joinColumn.referencedColumnName());
+        } else if (roleType == RoleType.DEPENDENT) {
+          jpaColumnNames.add(joinColumn.name());
+        }
+      }
+
+    }
+
+    private void buildRole() throws SecurityException, NoSuchFieldException {
+
+      if (currentRole == null) {
+        currentRole = new ReferentialConstraintRole();
+        String jpaAttributeType = null;
+        EntityType edmEntityType = null;
+
+        if (roleType == RoleType.PRINCIPAL) {
+          jpaAttributeType = jpaAttribute.getJavaType().getSimpleName();
+          if (jpaAttributeType.equals("List")) {
+            Type type =
+                ((ParameterizedType) jpaAttribute.getJavaMember().getDeclaringClass().getDeclaredField(
+                    jpaAttribute.getName()).getGenericType()).getActualTypeArguments()[0];
+            int lastIndexOfDot = type.toString().lastIndexOf(".");
+            jpaAttributeType = type.toString().substring(lastIndexOfDot + 1);
+          }
+          edmEntityType = entityTypeView.searchEdmEntityType(jpaAttributeType);
+        } else if (roleType == RoleType.DEPENDENT) {
+          edmEntityType =
+              entityTypeView.searchEdmEntityType(jpaAttribute.getDeclaringType().getJavaType().getSimpleName());
+        }
+
+        List<PropertyRef> propertyRefs = new ArrayList<PropertyRef>();
+        if (edmEntityType != null) {
+          for (String columnName : jpaColumnNames) {
+            for (Property property : edmEntityType.getProperties()) {
+              if (columnName.equals(((JPAEdmMapping) property.getMapping()).getJPAColumnName())) {
+                PropertyRef propertyRef = new PropertyRef();
+                propertyRef.setName(property.getName());
+                propertyRefs.add(propertyRef);
+                break;
+              }
+            }
+          }
+          currentRole.setPropertyRefs(propertyRefs);
+          if (propertyRefs.isEmpty()) {
+            isConsistent = false;
+            return;
+          }
+          AssociationEnd end = association.getEnd1();
+          if (end.getType().getName().equals(edmEntityType.getName())) {
+            currentRole.setRole(end.getRole());
+            isConsistent = true;
+          } else {
+            end = association.getEnd2();
+            if (end.getType().getName().equals(edmEntityType.getName())) {
+              currentRole.setRole(end.getRole());
+              isConsistent = true;
+            }
+          }
+        }
+
+      }
+    }
+
+    private void extractJoinColumns() {
+      /*
+       * Check against Static Buffer whether the join column was already
+       * extracted.
+       */
+      if (!jpaAttribute.equals(bufferedJPAAttribute)) {
+        bufferedJPAAttribute = jpaAttribute;
+        bufferedJoinColumns.clear();
+      } else if (bufferedJoinColumns.isEmpty()) {
+        roleExists = false;
+        return;
+      } else {
+        roleExists = true;
+        return;
+      }
+
+      AnnotatedElement annotatedElement = (AnnotatedElement) jpaAttribute.getJavaMember();
+
+      if (annotatedElement == null) {
+        return;
+      }
+
+      JoinColumn joinColumn = annotatedElement.getAnnotation(JoinColumn.class);
+      if (joinColumn == null) {
+        JoinColumns joinColumns = annotatedElement.getAnnotation(JoinColumns.class);
+
+        if (joinColumns != null) {
+          JoinColumn[] joinColumnArray = joinColumns.value();
+
+          for (JoinColumn element : joinColumnArray) {
+            bufferedJoinColumns.add(element);
+          }
+        } else {
+          return;
+        }
+      } else {
+        bufferedJoinColumns.add(joinColumn);
+      }
+      roleExists = true;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/63b621a8/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmSchema.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmSchema.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmSchema.java
new file mode 100644
index 0000000..f27accd
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmSchema.java
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ * 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.jpa.processor.core.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.provider.Association;
+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.NavigationProperty;
+import org.apache.olingo.odata2.api.edm.provider.Schema;
+import org.apache.olingo.odata2.jpa.processor.api.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmAssociationView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmComplexTypeView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmEntityContainerView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmEntitySetView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmEntityTypeView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmExtension;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmFunctionImportView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmModelView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmSchemaView;
+import org.apache.olingo.odata2.jpa.processor.core.access.model.JPAEdmNameBuilder;
+
+public class JPAEdmSchema extends JPAEdmBaseViewImpl implements JPAEdmSchemaView {
+
+  private Schema schema;
+  private JPAEdmComplexTypeView complexTypeView;
+  private JPAEdmEntityContainerView entityContainerView;
+  private JPAEdmAssociationView associationView = null;
+  private HashMap<Class<?>, String[]> customOperations = null;
+
+  public JPAEdmSchema(final JPAEdmModelView modelView) {
+    super(modelView);
+  }
+
+  @Override
+  public Schema getEdmSchema() {
+    return schema;
+  }
+
+  @Override
+  public JPAEdmEntityContainerView getJPAEdmEntityContainerView() {
+    return entityContainerView;
+  }
+
+  @Override
+  public JPAEdmComplexTypeView getJPAEdmComplexTypeView() {
+    return complexTypeView;
+  }
+
+  @Override
+  public JPAEdmBuilder getBuilder() {
+    if (builder == null) {
+      builder = new JPAEdmSchemaBuilder();
+    }
+
+    return builder;
+  }
+
+  @Override
+  public void clean() {
+    super.clean();
+    schema = null;
+  }
+
+  private class JPAEdmSchemaBuilder implements JPAEdmBuilder {
+    /*
+     * 
+     * Each call to build method creates a new EDM Schema. The newly created
+     * schema is built with Entity Containers, associations, Complex Types
+     * and Entity Types.
+     * 
+     * ************************************************************ Build
+     * EDM Schema - STEPS
+     * ************************************************************ 1) Build
+     * Name for EDM Schema 2) Build EDM Complex Types from JPA Embeddable
+     * Types 3) Add EDM Complex Types to EDM Schema 4) Build EDM Entity
+     * Container 5) Add EDM Entity Container to EDM Schema 6) Fetch Built
+     * EDM Entity Types from EDM Entity Container 7) Add EDM Entity Types to
+     * EDM Schema 8) Fetch Built EDM Association Sets from EDM Entity
+     * Container 9) Fetch Built EDM Associations from EDM Association Set
+     * 10) Add EDM Association to EDM Schema
+     * ************************************************************ Build
+     * EDM Schema - STEPS
+     * ************************************************************
+     */
+    @Override
+    public void build() throws ODataJPAModelException, ODataJPARuntimeException {
+
+      schema = new Schema();
+      JPAEdmNameBuilder.build(JPAEdmSchema.this);
+
+      associationView = new JPAEdmAssociation(JPAEdmSchema.this);
+
+      complexTypeView = new JPAEdmComplexType(JPAEdmSchema.this);
+      complexTypeView.getBuilder().build();
+
+      entityContainerView = new JPAEdmEntityContainer(JPAEdmSchema.this);
+      entityContainerView.getBuilder().build();
+      schema.setEntityContainers(entityContainerView.getConsistentEdmEntityContainerList());
+
+      JPAEdmEntitySetView entitySetView = entityContainerView.getJPAEdmEntitySetView();
+      if (entitySetView.isConsistent() && entitySetView.getJPAEdmEntityTypeView() != null) {
+        JPAEdmEntityTypeView entityTypeView = entitySetView.getJPAEdmEntityTypeView();
+        if (entityTypeView.isConsistent() && !entityTypeView.getConsistentEdmEntityTypes().isEmpty()) {
+          schema.setEntityTypes(entityTypeView.getConsistentEdmEntityTypes());
+        }
+      }
+      if (complexTypeView.isConsistent()) {
+        List<ComplexType> complexTypes = complexTypeView.getConsistentEdmComplexTypes();
+        List<ComplexType> existingComplexTypes = new ArrayList<ComplexType>();
+        for (ComplexType complexType : complexTypes) {
+          if (complexType != null && complexTypeView.isReferencedInKey(complexType.getName())) {// null check for
+                                                                                                // exclude
+            existingComplexTypes.add(complexType);
+          }
+        }
+        if (!existingComplexTypes.isEmpty()) {
+          schema.setComplexTypes(existingComplexTypes);
+        }
+      }
+
+      List<String> existingAssociationList = new ArrayList<String>();
+      if (associationView.isConsistent() && !associationView.getConsistentEdmAssociationList().isEmpty()) {
+
+        List<Association> consistentAssociationList = associationView.getConsistentEdmAssociationList();
+        schema.setAssociations(consistentAssociationList);
+        for (Association association : consistentAssociationList) {
+          existingAssociationList.add(association.getName());
+        }
+
+      }
+      List<EntityType> entityTypes =
+          entityContainerView.getJPAEdmEntitySetView().getJPAEdmEntityTypeView().getConsistentEdmEntityTypes();
+      List<NavigationProperty> navigationProperties;
+      if (entityTypes != null && !entityTypes.isEmpty()) {
+        for (EntityType entityType : entityTypes) {
+
+          List<NavigationProperty> consistentNavigationProperties = null;
+          navigationProperties = entityType.getNavigationProperties();
+          if (navigationProperties != null) {
+            consistentNavigationProperties = new ArrayList<NavigationProperty>();
+            for (NavigationProperty navigationProperty : navigationProperties) {
+              if (existingAssociationList.contains(navigationProperty.getRelationship().getName())) {
+                consistentNavigationProperties.add(navigationProperty);
+              }
+            }
+            if (consistentNavigationProperties.isEmpty()) {
+              entityType.setNavigationProperties(null);
+            } else {
+              entityType.setNavigationProperties(consistentNavigationProperties);
+            }
+          }
+
+        }
+      }
+
+      JPAEdmExtension edmExtension = getJPAEdmExtension();
+      if (edmExtension != null) {
+        edmExtension.extendJPAEdmSchema(JPAEdmSchema.this);
+        edmExtension.extendWithOperation(JPAEdmSchema.this);
+
+        JPAEdmFunctionImportView functionImportView = new JPAEdmFunctionImport(JPAEdmSchema.this);
+        functionImportView.getBuilder().build();
+        if (functionImportView.getConsistentFunctionImportList() != null) {
+          entityContainerView.getEdmEntityContainer().setFunctionImports(
+              functionImportView.getConsistentFunctionImportList());
+        }
+
+      }
+    }
+
+  }
+
+  @Override
+  public final JPAEdmAssociationView getJPAEdmAssociationView() {
+    return associationView;
+  }
+
+  @Override
+  public void registerOperations(final Class<?> customClass, final String[] methodNames) {
+    if (customOperations == null) {
+      customOperations = new HashMap<Class<?>, String[]>();
+    }
+
+    customOperations.put(customClass, methodNames);
+
+  }
+
+  @Override
+  public HashMap<Class<?>, String[]> getRegisteredOperations() {
+    return customOperations;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/63b621a8/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/_JPAEdmFunctionImportBuilder.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/_JPAEdmFunctionImportBuilder.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/_JPAEdmFunctionImportBuilder.java
new file mode 100644
index 0000000..94e7374
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/_JPAEdmFunctionImportBuilder.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * 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.jpa.processor.core.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.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.jpa.processor.api.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmComplexTypeView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmEntityTypeView;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmSchemaView;
+import org.apache.olingo.odata2.jpa.processor.core.access.model.JPAEdmNameBuilder;
+import org.apache.olingo.odata2.jpa.processor.core.access.model.JPATypeConvertor;
+
+@Deprecated
+public final class _JPAEdmFunctionImportBuilder {
+
+  private JPAEdmEntityTypeView jpaEdmEntityTypeView = null;
+  private JPAEdmComplexTypeView jpaEdmComplexTypeView = null;
+  private JPAEdmSchemaView schemaView;
+
+  public void setJPAEdmEntityTypeView(final JPAEdmEntityTypeView jpaEdmEntityTypeView) {
+    this.jpaEdmEntityTypeView = jpaEdmEntityTypeView;
+  }
+
+  public void setSchemaView(final JPAEdmSchemaView schemaView) {
+    this.schemaView = schemaView;
+  }
+
+  public void setJPAEdmComplexTypeView(final JPAEdmComplexTypeView jpaEdmComplexTypeView) {
+    this.jpaEdmComplexTypeView = jpaEdmComplexTypeView;
+  }
+
+  public FunctionImport buildFunctionImport(final Method method,
+      final org.apache.olingo.odata2.api.annotation.edm.FunctionImport annotation) throws ODataJPAModelException {
+
+    if (method != null && 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 {
+    org.apache.olingo.odata2.api.annotation.edm.FunctionImport.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();
+    }
+  }
+}