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

[46/51] [partial] initial commit

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/data/JPAEntityParser.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/data/JPAEntityParser.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/data/JPAEntityParser.java
new file mode 100644
index 0000000..72e81fa
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/data/JPAEntityParser.java
@@ -0,0 +1,423 @@
+/*******************************************************************************
+ * 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.access.data;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.EdmAssociationEnd;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmStructuralType;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmMapping;
+
+public final class JPAEntityParser {
+
+  /*
+   * List of buffers used by the Parser
+   */
+  private static short MAX_SIZE = 10;
+  public static final String ACCESS_MODIFIER_GET = "get";
+  public static final String ACCESS_MODIFIER_SET = "set";
+
+  private HashMap<String, HashMap<String, Method>> jpaEntityAccessMap = null;
+  private HashMap<String, HashMap<String, String>> jpaEmbeddableKeyMap = null;
+
+  private static JPAEntityParser jpaEntityParser;
+
+  private JPAEntityParser() {
+    jpaEntityAccessMap = new HashMap<String, HashMap<String, Method>>(
+        MAX_SIZE);
+    jpaEmbeddableKeyMap = new HashMap<String, HashMap<String, String>>();
+  };
+
+  public static final JPAEntityParser create() {
+    if (jpaEntityParser == null) {
+      jpaEntityParser = new JPAEntityParser();
+    }
+    return jpaEntityParser;
+  }
+
+  /**
+   * The method returns a Hash Map of Properties and values for selected
+   * properties of an EdmEntity Type
+   * 
+   * @param jpaEntity
+   * @param selectedItems
+   * @return a Hash Map of Properties and values for given selected properties
+   *         of an EdmEntity Type
+   * @throws ODataJPARuntimeException
+   */
+
+  public final HashMap<String, Object> parse2EdmPropertyValueMap(
+      final Object jpaEntity, final List<EdmProperty> selectPropertyList)
+      throws ODataJPARuntimeException {
+    HashMap<String, Object> edmEntity = new HashMap<String, Object>();
+    String methodName = null;
+    Method method = null;
+    for (int i = 0; i < selectPropertyList.size(); i++) {
+      String key = null;
+      Object propertyValue = null;
+      EdmProperty property = null;
+      property = selectPropertyList.get(i);
+
+      try {
+        methodName = getAccessModifierName(property.getName(),
+            property.getMapping(), ACCESS_MODIFIER_GET);
+        String[] nameParts = methodName.split("\\.");
+        if (nameParts.length > 1) {
+          Object propertyVal = new Object();
+          propertyVal = jpaEntity;
+          for (String namePart : nameParts) {
+            method = propertyVal.getClass().getMethod(
+                namePart, (Class<?>[]) null);
+            method.setAccessible(true);
+            propertyVal = method.invoke(propertyVal);
+          }
+          edmEntity.put(property.getName(), propertyVal);
+        } else {
+          method = jpaEntity.getClass().getMethod(methodName,
+              (Class<?>[]) null);
+          method.setAccessible(true);
+          propertyValue = method.invoke(jpaEntity);
+          key = property.getName();
+          if (property.getType().getKind()
+              .equals(EdmTypeKind.COMPLEX)) {
+            try {
+              propertyValue = parse2EdmPropertyValueMap(
+                  propertyValue,
+                  (EdmStructuralType) property.getType());
+            } catch (ODataJPARuntimeException e) {
+              throw e;
+            }
+          }
+          edmEntity.put(key, propertyValue);
+        }
+      } catch (EdmException e) {
+        throw ODataJPARuntimeException.throwException(
+            ODataJPARuntimeException.GENERAL.addContent(e
+                .getMessage()), e);
+      } catch (SecurityException e) {
+        throw ODataJPARuntimeException.throwException(
+            ODataJPARuntimeException.GENERAL.addContent(e
+                .getMessage()), e);
+      } catch (NoSuchMethodException e) {
+        throw ODataJPARuntimeException.throwException(
+            ODataJPARuntimeException.GENERAL.addContent(e
+                .getMessage()), e);
+      } catch (IllegalArgumentException e) {
+        throw ODataJPARuntimeException.throwException(
+            ODataJPARuntimeException.GENERAL.addContent(e
+                .getMessage()), e);
+      } catch (IllegalAccessException e) {
+        throw ODataJPARuntimeException.throwException(
+            ODataJPARuntimeException.GENERAL.addContent(e
+                .getMessage()), e);
+      } catch (InvocationTargetException e) {
+        throw ODataJPARuntimeException.throwException(
+            ODataJPARuntimeException.GENERAL.addContent(e
+                .getMessage()), e);
+      }
+    }
+
+    return edmEntity;
+  }
+
+  /**
+   * The method returns a Hash Map of Properties and values for an EdmEntity
+   * Type The method uses reflection on object jpaEntity to get the list of
+   * accessModifier method. Then uses the accessModifier method to extract the value from
+   * JPAEntity.
+   * 
+   * @param jpaEntity
+   * @param structuralType
+   * @return a Hash Map of Properties and values for given EdmEntity Type
+   * @throws ODataJPARuntimeException
+   */
+  public final HashMap<String, Object> parse2EdmPropertyValueMap(
+      final Object jpaEntity, final EdmStructuralType structuralType)
+      throws ODataJPARuntimeException {
+
+    if (jpaEntity == null || structuralType == null) {
+      return null;
+    }
+
+    String jpaEntityAccessKey = jpaEntity.getClass().getName();
+
+    if (!jpaEntityAccessMap.containsKey(jpaEntityAccessKey)) {
+      jpaEntityAccessMap.put(jpaEntityAccessKey,
+          getAccessModifier(jpaEntity, structuralType, ACCESS_MODIFIER_GET));
+    }
+
+    HashMap<String, Object> edmEntity = new HashMap<String, Object>();
+    HashMap<String, Method> getters = jpaEntityAccessMap
+        .get(jpaEntityAccessKey);
+    HashMap<String, String> embeddableKeys = jpaEmbeddableKeyMap
+        .get(jpaEntityAccessKey);
+
+    try {
+      for (String key : getters.keySet()) {
+
+        EdmProperty property = (EdmProperty) structuralType
+            .getProperty(key);
+
+        Method method = getters.get(key);
+        Object propertyValue = null;
+
+        if (method != null) {
+          getters.get(key).setAccessible(true);
+          propertyValue = getters.get(key).invoke(jpaEntity);
+        }
+
+        if (property.getType().getKind().equals(EdmTypeKind.COMPLEX)) {
+          propertyValue = parse2EdmPropertyValueMap(propertyValue,
+              (EdmStructuralType) property.getType());
+        }
+
+        edmEntity.put(key, propertyValue);
+
+      }
+
+      if (embeddableKeys != null) {
+        for (String key : embeddableKeys.keySet()) {
+          String name = embeddableKeys.get(key);
+          String[] nameParts = name.split("\\.");
+          Object propertyValue = jpaEntity;
+          Method method = null;
+          for (String namePart : nameParts) {
+            method = propertyValue.getClass().getMethod(
+                namePart, (Class<?>[]) null);
+            method.setAccessible(true);
+            propertyValue = method.invoke(propertyValue);
+          }
+          edmEntity.put(key, propertyValue);
+        }
+      }
+    } catch (EdmException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (SecurityException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (NoSuchMethodException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (IllegalArgumentException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (IllegalAccessException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (InvocationTargetException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+    return edmEntity;
+  }
+
+  // This method appends the associated entities as a java list to an expanded
+  // map of a source entity
+  public final HashMap<String, Object> parse2EdmNavigationValueMap(
+      final Object jpaEntity, final List<EdmNavigationProperty> navigationPropertyList)
+      throws ODataJPARuntimeException {
+    Object result = null;
+    String methodName = null;
+    HashMap<String, Object> navigationMap = new HashMap<String, Object>();
+    if (navigationPropertyList != null
+        && navigationPropertyList.size() != 0) {
+
+      try {
+        for (EdmNavigationProperty navigationProperty : navigationPropertyList) {
+          methodName = getAccessModifierName(navigationProperty.getName(),
+              navigationProperty.getMapping(), ACCESS_MODIFIER_GET);
+          Method getterMethod = jpaEntity.getClass()
+              .getDeclaredMethod(methodName, (Class<?>[]) null);
+          getterMethod.setAccessible(true);
+          result = getterMethod.invoke(jpaEntity);
+          navigationMap.put(navigationProperty.getName(), result);
+        }
+      } catch (IllegalArgumentException e) {
+        throw ODataJPARuntimeException.throwException(
+            ODataJPARuntimeException.GENERAL.addContent(e
+                .getMessage()), e);
+      } catch (IllegalAccessException e) {
+        throw ODataJPARuntimeException.throwException(
+            ODataJPARuntimeException.GENERAL.addContent(e
+                .getMessage()), e);
+      } catch (InvocationTargetException e) {
+        throw ODataJPARuntimeException.throwException(
+            ODataJPARuntimeException.GENERAL.addContent(e
+                .getMessage()), e);
+      } catch (EdmException e) {
+        throw ODataJPARuntimeException.throwException(
+            ODataJPARuntimeException.GENERAL.addContent(e
+                .getMessage()), e);
+      } catch (SecurityException e) {
+        throw ODataJPARuntimeException.throwException(
+            ODataJPARuntimeException.GENERAL.addContent(e
+                .getMessage()), e);
+      } catch (NoSuchMethodException e) {
+        throw ODataJPARuntimeException.throwException(
+            ODataJPARuntimeException.GENERAL.addContent(e
+                .getMessage()), e);
+      }
+    }
+    return navigationMap;
+  }
+
+  public HashMap<String, Method> getAccessModifier(final Object jpaEntity,
+      final EdmStructuralType structuralType, final String accessModifier) throws ODataJPARuntimeException {
+
+    HashMap<String, Method> accessModifierMap = new HashMap<String, Method>();
+    HashMap<String, String> embeddableKey = new HashMap<String, String>();
+    try {
+      for (String propertyName : structuralType.getPropertyNames()) {
+
+        EdmProperty property = (EdmProperty) structuralType
+            .getProperty(propertyName);
+
+        String name = getAccessModifierName(property.getName(),
+            property.getMapping(), accessModifier);
+        String[] nameParts = name.split("\\.");
+        if (nameParts.length > 1) {
+          embeddableKey.put(propertyName, name);
+        } else {
+          accessModifierMap.put(
+              propertyName,
+              jpaEntity.getClass().getMethod(name,
+                  (Class<?>[]) null));
+        }
+      }
+    } catch (NoSuchMethodException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (SecurityException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (EdmException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+
+    if (!embeddableKey.isEmpty()) {
+      jpaEmbeddableKeyMap.put(jpaEntity.getClass().getName(),
+          embeddableKey);
+    }
+    return accessModifierMap;
+  }
+
+  private static String getAccessModifierName(final String propertyName, final EdmMapping mapping, final String accessModifier)
+      throws ODataJPARuntimeException {
+    String name = null;
+    StringBuilder builder = new StringBuilder();
+    String[] nameParts = {};
+    if (mapping == null || mapping.getInternalName() == null) {
+      name = propertyName;
+    } else {
+      name = mapping.getInternalName();
+    }
+    if (name != null) {
+      nameParts = name.split("\\.");
+    }
+    if (nameParts.length == 1) {
+      if (name != null) {
+        char c = Character.toUpperCase(name.charAt(0));
+
+        builder.append(accessModifier).append(c).append(name.substring(1))
+            .toString();
+      }
+    } else if (nameParts.length > 1) {
+
+      for (int i = 0; i < nameParts.length; i++) {
+        name = nameParts[i];
+        char c = Character.toUpperCase(name.charAt(0));
+        if (i == 0) {
+          builder.append(accessModifier).append(c).append(name.substring(1));
+        } else {
+          builder.append(".").append(accessModifier).append(c)
+              .append(name.substring(1));
+        }
+      }
+    } else {
+      return null;
+    }
+
+    if (builder.length() > 0) {
+      return builder.toString();
+    } else {
+      return null;
+    }
+
+  }
+
+  public Method getAccessModifier(final Object jpaEntity, final EdmNavigationProperty navigationProperty, final String accessModifier)
+      throws ODataJPARuntimeException {
+
+    try {
+
+      String name = getAccessModifierName(navigationProperty.getName(),
+          navigationProperty.getMapping(), accessModifier);
+
+      Class<?>[] params = null;
+      if (accessModifier.equals(ACCESS_MODIFIER_SET)) {
+        EdmAssociationEnd end = navigationProperty.getRelationship().getEnd(navigationProperty.getToRole());
+        switch (end.getMultiplicity()) {
+        case MANY:
+          params = new Class<?>[] { List.class };
+          break;
+        case ONE:
+          params = new Class<?>[] { ((JPAEdmMapping) end.getEntityType().getMapping()).getJPAType() };
+        default:
+          break;
+        }
+      }
+      return jpaEntity.getClass().getMethod(name,
+          params);
+
+    } catch (NoSuchMethodException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (SecurityException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (EdmException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/data/JPAExpandCallBack.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/data/JPAExpandCallBack.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/data/JPAExpandCallBack.java
new file mode 100644
index 0000000..eb875d8
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/data/JPAExpandCallBack.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * 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.access.data;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.ODataCallback;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
+import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties.ODataEntityProviderPropertiesBuilder;
+import org.apache.olingo.odata2.api.ep.callback.OnWriteEntryContent;
+import org.apache.olingo.odata2.api.ep.callback.OnWriteFeedContent;
+import org.apache.olingo.odata2.api.ep.callback.WriteCallbackContext;
+import org.apache.olingo.odata2.api.ep.callback.WriteEntryCallbackContext;
+import org.apache.olingo.odata2.api.ep.callback.WriteEntryCallbackResult;
+import org.apache.olingo.odata2.api.ep.callback.WriteFeedCallbackContext;
+import org.apache.olingo.odata2.api.ep.callback.WriteFeedCallbackResult;
+import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
+import org.apache.olingo.odata2.api.uri.NavigationPropertySegment;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+
+public class JPAExpandCallBack implements OnWriteFeedContent, OnWriteEntryContent, ODataCallback {
+
+  private URI baseUri;
+  private List<ArrayList<NavigationPropertySegment>> expandList;
+  private EdmEntitySet nextEntitySet = null;
+
+  private JPAExpandCallBack(final URI baseUri, final List<ArrayList<NavigationPropertySegment>> expandList) {
+    super();
+    this.baseUri = baseUri;
+    this.expandList = expandList;
+  }
+
+  @Override
+  public WriteEntryCallbackResult retrieveEntryResult(
+      final WriteEntryCallbackContext context) {
+    WriteEntryCallbackResult result = new WriteEntryCallbackResult();
+    Map<String, Object> entry = context.getEntryData();
+    Map<String, Object> edmPropertyValueMap = null;
+    List<EdmNavigationProperty> currentNavPropertyList = null;
+    Map<String, ExpandSelectTreeNode> navigationLinks = null;
+    JPAEntityParser jpaResultParser = JPAEntityParser.create();
+    EdmNavigationProperty currentNavigationProperty = context.getNavigationProperty();
+    try {
+      Object inlinedEntry = entry.get(currentNavigationProperty.getName());
+      if (nextEntitySet == null) {
+        nextEntitySet = context.getSourceEntitySet().getRelatedEntitySet(currentNavigationProperty);
+      }
+      edmPropertyValueMap = jpaResultParser.parse2EdmPropertyValueMap(inlinedEntry, nextEntitySet.getEntityType());
+      result.setEntryData(edmPropertyValueMap);
+      navigationLinks = context.getCurrentExpandSelectTreeNode().getLinks();
+      if (navigationLinks.size() > 0)
+      {
+        currentNavPropertyList = new ArrayList<EdmNavigationProperty>();
+        currentNavPropertyList.add(getNextNavigationProperty(context.getSourceEntitySet().getEntityType(), context.getNavigationProperty()));
+        HashMap<String, Object> navigationMap = jpaResultParser.parse2EdmNavigationValueMap(inlinedEntry, currentNavPropertyList);
+        edmPropertyValueMap.putAll(navigationMap);
+        result.setEntryData(edmPropertyValueMap);
+      }
+      result.setInlineProperties(getInlineEntityProviderProperties(context));
+    } catch (EdmException e) {
+
+    } catch (ODataJPARuntimeException e) {
+
+    }
+
+    return result;
+  }
+
+  @Override
+  public WriteFeedCallbackResult retrieveFeedResult(
+      final WriteFeedCallbackContext context) {
+    WriteFeedCallbackResult result = new WriteFeedCallbackResult();
+    HashMap<String, Object> inlinedEntry = (HashMap<String, Object>) context.getEntryData();
+    List<Map<String, Object>> edmEntityList = new ArrayList<Map<String, Object>>();
+    Map<String, Object> edmPropertyValueMap = null;
+    JPAEntityParser jpaResultParser = JPAEntityParser.create();
+    List<EdmNavigationProperty> currentNavPropertyList = null;
+    EdmNavigationProperty currentNavigationProperty = context.getNavigationProperty();
+    try {
+      @SuppressWarnings({ "unchecked" })
+      List<Object> listOfItems = (List<Object>) inlinedEntry.get(context.getNavigationProperty().getName());
+      if (nextEntitySet == null) {
+        nextEntitySet = context.getSourceEntitySet().getRelatedEntitySet(currentNavigationProperty);
+      }
+      for (Object object : listOfItems)
+      {
+        edmPropertyValueMap = jpaResultParser.parse2EdmPropertyValueMap(object, nextEntitySet.getEntityType());
+        edmEntityList.add(edmPropertyValueMap);
+      }
+      result.setFeedData(edmEntityList);
+      if (context.getCurrentExpandSelectTreeNode().getLinks().size() > 0)
+      {
+        currentNavPropertyList = new ArrayList<EdmNavigationProperty>();
+        currentNavPropertyList.add(getNextNavigationProperty(context.getSourceEntitySet().getEntityType(), context.getNavigationProperty()));
+        int count = 0;
+        for (Object object : listOfItems)
+        {
+          HashMap<String, Object> navigationMap = jpaResultParser.parse2EdmNavigationValueMap(object, currentNavPropertyList);
+          edmEntityList.get(count).putAll(navigationMap);
+          count++;
+        }
+        result.setFeedData(edmEntityList);
+      }
+      result.setInlineProperties(getInlineEntityProviderProperties(context));
+    } catch (EdmException e) {
+
+    } catch (ODataJPARuntimeException e) {
+
+    }
+    return result;
+  }
+
+  private EdmNavigationProperty getNextNavigationProperty(
+      final EdmEntityType sourceEntityType, final EdmNavigationProperty navigationProperty) throws EdmException {
+    int count;
+    for (ArrayList<NavigationPropertySegment> navPropSegments : expandList)
+    {
+      count = 0;
+      for (NavigationPropertySegment navPropSegment : navPropSegments)
+      {
+        EdmNavigationProperty navProperty = navPropSegment.getNavigationProperty();
+        if (navProperty.getFromRole().equalsIgnoreCase(sourceEntityType.getName()) && navProperty.getName().equals(navigationProperty.getName())) {
+          return navPropSegments.get(count + 1).getNavigationProperty();
+        } else {
+          count++;
+        }
+
+      }
+    }
+    return null;
+  }
+
+  public static <T> Map<String, ODataCallback> getCallbacks(final URI baseUri, final ExpandSelectTreeNode expandSelectTreeNode, final List<ArrayList<NavigationPropertySegment>> expandList) throws EdmException {
+    Map<String, ODataCallback> callbacks = new HashMap<String, ODataCallback>();
+
+    for (String navigationPropertyName : expandSelectTreeNode.getLinks().keySet()) {
+      callbacks.put(navigationPropertyName, new JPAExpandCallBack(baseUri, expandList));
+    }
+
+    return callbacks;
+
+  }
+
+  private EntityProviderWriteProperties getInlineEntityProviderProperties(final WriteCallbackContext context) throws EdmException {
+    ODataEntityProviderPropertiesBuilder propertiesBuilder = EntityProviderWriteProperties.serviceRoot(baseUri);
+    propertiesBuilder.callbacks(getCallbacks(baseUri, context.getCurrentExpandSelectTreeNode(), expandList));
+    propertiesBuilder.expandSelectTree(context.getCurrentExpandSelectTreeNode());
+    return propertiesBuilder.build();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/data/JPAFunctionContext.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/data/JPAFunctionContext.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/data/JPAFunctionContext.java
new file mode 100644
index 0000000..ecebd48
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/data/JPAFunctionContext.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * 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.access.data;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
+import org.apache.olingo.odata2.api.edm.EdmLiteral;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.edm.EdmParameter;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+import org.apache.olingo.odata2.api.uri.info.GetFunctionImportUriInfo;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAFunction;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAMethodContext;
+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.JPAEdmMapping;
+
+public class JPAFunctionContext extends JPAMethodContext {
+
+  public class JPAFunctionContextBuilder extends JPAMethodContextBuilder {
+
+    protected GetFunctionImportUriInfo functiontView;
+    private EdmFunctionImport functionImport;
+    private EdmMapping mapping;
+
+    @Override
+    public JPAMethodContext build() throws ODataJPAModelException,
+        ODataJPARuntimeException {
+      if (functiontView != null) {
+
+        functionImport = functiontView.getFunctionImport();
+        try {
+          mapping = functionImport.getMapping();
+
+          List<JPAFunction> jpaFunctionList = new ArrayList<JPAFunction>();
+          jpaFunctionList.add(generateJPAFunction());
+          setJpaFunction(jpaFunctionList);
+          setEnclosingObject(generateEnclosingObject());
+        } catch (EdmException e) {
+          throw ODataJPARuntimeException.throwException(
+              ODataJPARuntimeException.GENERAL.addContent(e
+                  .getMessage()), e);
+        } catch (InstantiationException e) {
+          throw ODataJPARuntimeException.throwException(
+              ODataJPARuntimeException.GENERAL.addContent(e
+                  .getMessage()), e);
+        } catch (IllegalAccessException e) {
+          throw ODataJPARuntimeException.throwException(
+              ODataJPARuntimeException.GENERAL.addContent(e
+                  .getMessage()), e);
+        } catch (IllegalArgumentException e) {
+          throw ODataJPARuntimeException.throwException(
+              ODataJPARuntimeException.GENERAL.addContent(e
+                  .getMessage()), e);
+        } catch (InvocationTargetException e) {
+          throw ODataJPARuntimeException.throwException(
+              ODataJPARuntimeException.GENERAL.addContent(e
+                  .getMessage()), e);
+        } catch (NoSuchMethodException e) {
+          throw ODataJPARuntimeException.throwException(
+              ODataJPARuntimeException.GENERAL.addContent(e
+                  .getMessage()), e);
+        } catch (SecurityException e) {
+          throw ODataJPARuntimeException.throwException(
+              ODataJPARuntimeException.GENERAL.addContent(e
+                  .getMessage()), e);
+        }
+      }
+
+      return JPAFunctionContext.this;
+    }
+
+    private JPAFunction generateJPAFunction() throws EdmException,
+        NoSuchMethodException, SecurityException,
+        ODataJPAModelException, ODataJPARuntimeException {
+
+      Class<?>[] parameterTypes = getParameterTypes();
+      Method method = getMethod(parameterTypes);
+      Type returnType = getReturnType();
+      Object[] args = getAruguments();
+
+      JPAFunction jpafunction = new JPAFunction(method, parameterTypes,
+          returnType, args);
+
+      return jpafunction;
+    }
+
+    private Object[] getAruguments() throws EdmException {
+      Map<String, EdmLiteral> edmArguements = functiontView
+          .getFunctionImportParameters();
+
+      if (edmArguements == null) {
+        return null;
+      } else {
+        Object[] args = new Object[edmArguements.size()];
+        int i = 0;
+        for (String paramName : functionImport.getParameterNames()) {
+          EdmLiteral literal = edmArguements.get(paramName);
+          EdmParameter parameter = functionImport
+              .getParameter(paramName);
+          JPAEdmMapping mapping = (JPAEdmMapping) parameter
+              .getMapping();
+          args[i] = convertArguement(literal, parameter.getFacets(),
+              mapping.getJPAType());
+          i++;
+        }
+        return args;
+      }
+
+    }
+
+    private Object convertArguement(final EdmLiteral edmLiteral,
+        final EdmFacets facets, final Class<?> targetType)
+        throws EdmSimpleTypeException {
+      EdmSimpleType edmType = edmLiteral.getType();
+      Object value = edmType.valueOfString(edmLiteral.getLiteral(),
+          EdmLiteralKind.DEFAULT, facets, targetType);
+
+      return value;
+    }
+
+    private Class<?>[] getParameterTypes() throws EdmException {
+
+      Class<?>[] parameterTypes = new Class<?>[functionImport
+          .getParameterNames().size()];
+      int i = 0;
+      for (String parameterName : functionImport.getParameterNames()) {
+        EdmParameter parameter = functionImport
+            .getParameter(parameterName);
+        parameterTypes[i] = ((JPAEdmMapping) parameter.getMapping())
+            .getJPAType();
+        i++;
+      }
+
+      return parameterTypes;
+    }
+
+    private Method getMethod(final Class<?>[] parameterTypes)
+        throws NoSuchMethodException, SecurityException {
+
+      Class<?> type = ((JPAEdmMapping) mapping).getJPAType();
+      Method method;
+      method = type.getMethod(mapping.getInternalName(), parameterTypes);
+
+      return method;
+    }
+
+    private Type getReturnType() throws ODataJPAModelException,
+        ODataJPARuntimeException, EdmException {
+      return null;
+    }
+
+    private Object generateEnclosingObject() throws InstantiationException,
+        IllegalAccessException, IllegalArgumentException,
+        InvocationTargetException, NoSuchMethodException,
+        SecurityException {
+
+      Class<?> type = ((JPAEdmMapping) mapping).getJPAType();
+      Object[] params = null;
+
+      return type.getConstructor((Class<?>[]) params).newInstance(params);
+
+    }
+
+    @Override
+    protected void setResultsView(final Object resultsView) {
+      if (resultsView instanceof GetFunctionImportUriInfo) {
+        functiontView = (GetFunctionImportUriInfo) resultsView;
+      }
+
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/data/JPAProcessorImpl.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/data/JPAProcessorImpl.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/data/JPAProcessorImpl.java
new file mode 100644
index 0000000..5ff10b0
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/data/JPAProcessorImpl.java
@@ -0,0 +1,434 @@
+/*******************************************************************************
+ * 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.access.data;
+
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityLinkUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetLinksUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetFunctionImportUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+import org.apache.olingo.odata2.processor.api.jpa.ODataJPAContext;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAFunction;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAMethodContext;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAProcessor;
+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.jpql.JPQLContext;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLContextType;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLStatement;
+import org.apache.olingo.odata2.processor.core.jpa.cud.JPACreateRequest;
+import org.apache.olingo.odata2.processor.core.jpa.cud.JPALink;
+import org.apache.olingo.odata2.processor.core.jpa.cud.JPAUpdateRequest;
+
+public class JPAProcessorImpl implements JPAProcessor {
+
+  ODataJPAContext oDataJPAContext;
+  EntityManager em;
+
+  public JPAProcessorImpl(final ODataJPAContext oDataJPAContext) {
+    this.oDataJPAContext = oDataJPAContext;
+    em = oDataJPAContext.getEntityManager();
+  }
+
+  /* Process Function Import Request */
+  @SuppressWarnings("unchecked")
+  @Override
+  public List<Object> process(final GetFunctionImportUriInfo uriParserResultView)
+      throws ODataJPAModelException, ODataJPARuntimeException {
+
+    JPAMethodContext jpaMethodContext = JPAMethodContext.createBuilder(
+        JPQLContextType.FUNCTION, uriParserResultView).build();
+
+    List<Object> resultObj = null;
+
+    try {
+
+      JPAFunction jpaFunction = jpaMethodContext.getJPAFunctionList()
+          .get(0);
+      Method method = jpaFunction.getFunction();
+      Object[] args = jpaFunction.getArguments();
+
+      if (uriParserResultView.getFunctionImport().getReturnType()
+          .getMultiplicity().equals(EdmMultiplicity.MANY)) {
+
+        resultObj = (List<Object>) method.invoke(
+            jpaMethodContext.getEnclosingObject(), args);
+      } else {
+        resultObj = new ArrayList<Object>();
+        Object result = method.invoke(
+            jpaMethodContext.getEnclosingObject(), args);
+        resultObj.add(result);
+      }
+
+    } catch (EdmException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (IllegalAccessException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (IllegalArgumentException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getMessage()), e);
+    } catch (InvocationTargetException e) {
+      throw ODataJPARuntimeException
+          .throwException(ODataJPARuntimeException.GENERAL
+              .addContent(e.getTargetException().getMessage()), e.getTargetException());
+    }
+
+    return resultObj;
+  }
+
+  /* Process Get Entity Set Request (Query) */
+  @SuppressWarnings("unchecked")
+  @Override
+  public <T> List<T> process(final GetEntitySetUriInfo uriParserResultView)
+      throws ODataJPAModelException, ODataJPARuntimeException {
+
+    if (uriParserResultView.getFunctionImport() != null) {
+      return (List<T>) process((GetFunctionImportUriInfo) uriParserResultView);
+    }
+    JPQLContextType contextType = null;
+    try {
+      if (!uriParserResultView.getStartEntitySet().getName()
+          .equals(uriParserResultView.getTargetEntitySet().getName())) {
+        contextType = JPQLContextType.JOIN;
+      } else {
+        contextType = JPQLContextType.SELECT;
+      }
+
+    } catch (EdmException e) {
+      ODataJPARuntimeException.throwException(
+          ODataJPARuntimeException.GENERAL, e);
+    }
+
+    JPQLContext jpqlContext = JPQLContext.createBuilder(contextType,
+        uriParserResultView).build();
+
+    JPQLStatement jpqlStatement = JPQLStatement.createBuilder(jpqlContext)
+        .build();
+    Query query = null;
+    try {
+      query = em.createQuery(jpqlStatement.toString());
+      // $top/$skip with $inlinecount case handled in response builder to avoid multiple DB call
+      if (uriParserResultView.getSkip() != null && uriParserResultView.getInlineCount() == null) {
+        query.setFirstResult(uriParserResultView.getSkip());
+      }
+
+      if (uriParserResultView.getTop() != null && uriParserResultView.getInlineCount() == null) {
+        if (uriParserResultView.getTop() == 0) {
+          List<T> resultList = new ArrayList<T>();
+          return resultList;
+        } else {
+          query.setMaxResults(uriParserResultView.getTop());
+        }
+      }
+      return query.getResultList();
+    } catch (IllegalArgumentException e) {
+      throw ODataJPARuntimeException.throwException(
+          ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
+    }
+  }
+
+  /* Process Get Entity Request (Read) */
+  @Override
+  public <T> Object process(GetEntityUriInfo uriParserResultView)
+      throws ODataJPAModelException, ODataJPARuntimeException {
+
+    JPQLContextType contextType = null;
+    try {
+      if (uriParserResultView instanceof GetEntityUriInfo) {
+        uriParserResultView = ((GetEntityUriInfo) uriParserResultView);
+        if (!((GetEntityUriInfo) uriParserResultView).getStartEntitySet().getName()
+            .equals(((GetEntityUriInfo) uriParserResultView).getTargetEntitySet().getName())) {
+          contextType = JPQLContextType.JOIN_SINGLE;
+        } else {
+          contextType = JPQLContextType.SELECT_SINGLE;
+        }
+      }
+    } catch (EdmException e) {
+      ODataJPARuntimeException.throwException(
+          ODataJPARuntimeException.GENERAL, e);
+    }
+
+    return readEntity(uriParserResultView, contextType);
+  }
+
+  /* Process $count for Get Entity Set Request */
+  @Override
+  public long process(final GetEntitySetCountUriInfo resultsView)
+      throws ODataJPAModelException, ODataJPARuntimeException {
+
+    JPQLContextType contextType = null;
+    try {
+      if (!resultsView.getStartEntitySet().getName()
+          .equals(resultsView.getTargetEntitySet().getName())) {
+        contextType = JPQLContextType.JOIN_COUNT;
+      } else {
+        contextType = JPQLContextType.SELECT_COUNT;
+      }
+    } catch (EdmException e) {
+      ODataJPARuntimeException.throwException(
+          ODataJPARuntimeException.GENERAL, e);
+    }
+
+    JPQLContext jpqlContext = JPQLContext.createBuilder(contextType,
+        resultsView).build();
+
+    JPQLStatement jpqlStatement = JPQLStatement.createBuilder(jpqlContext)
+        .build();
+    Query query = null;
+    try {
+
+      query = em.createQuery(jpqlStatement.toString());
+      List<?> resultList = query.getResultList();
+      if (resultList != null && resultList.size() == 1) {
+        return Long.valueOf(resultList.get(0).toString());
+      }
+    } catch (IllegalArgumentException e) {
+      throw ODataJPARuntimeException.throwException(
+          ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
+    }
+    return 0;
+  }
+
+  /* Process $count for Get Entity Request */
+  @Override
+  public long process(final GetEntityCountUriInfo resultsView) throws ODataJPAModelException, ODataJPARuntimeException {
+
+    JPQLContextType contextType = null;
+    try {
+      if (!resultsView.getStartEntitySet().getName()
+          .equals(resultsView.getTargetEntitySet().getName())) {
+        contextType = JPQLContextType.JOIN_COUNT;
+      } else {
+        contextType = JPQLContextType.SELECT_COUNT;
+      }
+    } catch (EdmException e) {
+      ODataJPARuntimeException.throwException(
+          ODataJPARuntimeException.GENERAL, e);
+    }
+
+    JPQLContext jpqlContext = JPQLContext.createBuilder(contextType,
+        resultsView).build();
+
+    JPQLStatement jpqlStatement = JPQLStatement.createBuilder(jpqlContext)
+        .build();
+    Query query = null;
+    try {
+
+      query = em.createQuery(jpqlStatement.toString());
+      List<?> resultList = query.getResultList();
+      if (resultList != null && resultList.size() == 1) {
+        return Long.valueOf(resultList.get(0).toString());
+      }
+    } catch (IllegalArgumentException e) {
+      throw ODataJPARuntimeException.throwException(
+          ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
+    }
+
+    return 0;
+  }
+
+  /* Process Create Entity Request */
+  @Override
+  public <T> List<T> process(final PostUriInfo createView, final InputStream content,
+      final String requestedContentType) throws ODataJPAModelException,
+      ODataJPARuntimeException {
+
+    JPACreateRequest jpaCreateRequest = new JPACreateRequest(em
+        .getEntityManagerFactory().getMetamodel());
+    List<T> createObjectList = jpaCreateRequest.process(createView, content,
+        requestedContentType);
+    try {
+      em.getTransaction().begin();
+      Object jpaEntity = createObjectList.get(0);
+
+      JPALink link = new JPALink(oDataJPAContext);
+      link.setSourceJPAEntity(jpaEntity);
+      link.create(createView, content, requestedContentType, requestedContentType);
+      em.persist(jpaEntity);
+      if (em.contains(jpaEntity)) {
+        em.getTransaction().commit();
+        return createObjectList;
+      }
+    } catch (Exception e) {
+      em.getTransaction().rollback();
+      throw ODataJPARuntimeException.throwException(
+          ODataJPARuntimeException.ERROR_JPQL_CREATE_REQUEST, e);
+    }
+    return null;
+  }
+
+  /* Process Update Entity Request */
+  @Override
+  public <T> Object process(PutMergePatchUriInfo updateView,
+      final InputStream content, final String requestContentType)
+      throws ODataJPAModelException, ODataJPARuntimeException {
+
+    JPQLContextType contextType = null;
+    try {
+      if (updateView instanceof PutMergePatchUriInfo) {
+        updateView = ((PutMergePatchUriInfo) updateView);
+        if (!((PutMergePatchUriInfo) updateView).getStartEntitySet().getName()
+            .equals(((PutMergePatchUriInfo) updateView).getTargetEntitySet().getName())) {
+          contextType = JPQLContextType.JOIN_SINGLE;
+        } else {
+          contextType = JPQLContextType.SELECT_SINGLE;
+        }
+      }
+    } catch (EdmException e) {
+      ODataJPARuntimeException.throwException(
+          ODataJPARuntimeException.GENERAL, e);
+    }
+
+    JPAUpdateRequest jpaUpdateRequest = new JPAUpdateRequest();
+    Object updateObject = readEntity(updateView, contextType);
+    try {
+      em.getTransaction().begin();
+      jpaUpdateRequest.process(updateObject, updateView, content,
+          requestContentType);
+      em.flush();
+      em.getTransaction().commit();
+    } catch (Exception e) {
+      em.getTransaction().rollback();
+      throw ODataJPARuntimeException.throwException(
+          ODataJPARuntimeException.ERROR_JPQL_UPDATE_REQUEST, e);
+    }
+    return updateObject;
+  }
+
+  /* Process Delete Entity Request */
+  @Override
+  public Object process(DeleteUriInfo uriParserResultView, final String contentType)
+      throws ODataJPAModelException, ODataJPARuntimeException {
+    JPQLContextType contextType = null;
+    try {
+      if (uriParserResultView instanceof DeleteUriInfo) {
+        uriParserResultView = ((DeleteUriInfo) uriParserResultView);
+        if (!((DeleteUriInfo) uriParserResultView).getStartEntitySet().getName()
+            .equals(((DeleteUriInfo) uriParserResultView).getTargetEntitySet().getName())) {
+          contextType = JPQLContextType.JOIN_SINGLE;
+        } else {
+          contextType = JPQLContextType.SELECT_SINGLE;
+        }
+      }
+    } catch (EdmException e) {
+      ODataJPARuntimeException.throwException(
+          ODataJPARuntimeException.GENERAL, e);
+    }
+
+    // First read the entity with read operation.
+    Object selectedObject = readEntity(uriParserResultView, contextType);
+    // Read operation done. This object would be passed on to entity manager for delete
+    if (selectedObject != null) {
+      try {
+        em.getTransaction().begin();
+        em.remove(selectedObject);
+        em.flush();
+        em.getTransaction().commit();
+      } catch (Exception e) {
+        em.getTransaction().rollback();
+        throw ODataJPARuntimeException.throwException(
+            ODataJPARuntimeException.ERROR_JPQL_DELETE_REQUEST, e);
+      }
+    }
+    return selectedObject;
+  }
+
+  /* Process Get Entity Link Request */
+  @Override
+  public Object process(final GetEntityLinkUriInfo uriParserResultView)
+      throws ODataJPAModelException, ODataJPARuntimeException {
+
+    return this.process((GetEntityUriInfo) uriParserResultView);
+  }
+
+  /* Process Get Entity Set Link Request */
+  @Override
+  public <T> List<T> process(final GetEntitySetLinksUriInfo uriParserResultView)
+      throws ODataJPAModelException, ODataJPARuntimeException {
+    return this.process((GetEntitySetUriInfo) uriParserResultView);
+  }
+
+  @Override
+  public void process(final PostUriInfo uriInfo,
+      final InputStream content, final String requestContentType, final String contentType)
+      throws ODataJPARuntimeException, ODataJPAModelException {
+    JPALink link = new JPALink(oDataJPAContext);
+    link.create(uriInfo, content, requestContentType, contentType);
+    link.save();
+  }
+
+  /* Common method for Read and Delete */
+  private Object readEntity(final Object uriParserResultView, final JPQLContextType contextType)
+      throws ODataJPAModelException, ODataJPARuntimeException {
+
+    Object selectedObject = null;
+
+    if (uriParserResultView instanceof DeleteUriInfo || uriParserResultView instanceof GetEntityUriInfo || uriParserResultView instanceof PutMergePatchUriInfo) {
+
+      JPQLContext selectJPQLContext = JPQLContext.createBuilder(
+          contextType, uriParserResultView).build();
+
+      JPQLStatement selectJPQLStatement = JPQLStatement.createBuilder(
+          selectJPQLContext).build();
+      Query query = null;
+      try {
+        query = em.createQuery(selectJPQLStatement.toString());
+        if (!query.getResultList().isEmpty()) {
+          selectedObject = query.getResultList().get(0);
+        }
+      } catch (IllegalArgumentException e) {
+        throw ODataJPARuntimeException.throwException(
+            ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
+      }
+    }
+    return selectedObject;
+  }
+
+  @Override
+  public void process(final PutMergePatchUriInfo putUriInfo,
+      final InputStream content, final String requestContentType, final String contentType)
+      throws ODataJPARuntimeException, ODataJPAModelException {
+    JPALink link = new JPALink(oDataJPAContext);
+    link.update(putUriInfo, content, requestContentType, contentType);
+    link.save();
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/EdmTypeConvertor.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/EdmTypeConvertor.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/EdmTypeConvertor.java
new file mode 100644
index 0000000..fb07fb7
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/EdmTypeConvertor.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * 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.access.model;
+
+import java.math.BigDecimal;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.UUID;
+
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.edm.EdmType;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+
+public class EdmTypeConvertor {
+
+  public static Class<?> convertToJavaType(final EdmType edmType) throws ODataJPAModelException, ODataJPARuntimeException {
+    if (edmType instanceof EdmSimpleType) {
+        EdmSimpleType edmSimpleType = (EdmSimpleType) edmType;
+        if (edmSimpleType == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()) {
+          return String.class;
+        }
+        else if (edmSimpleType == EdmSimpleTypeKind.Int64.getEdmSimpleTypeInstance()) {
+          return Long.TYPE;
+        }
+        else if (edmSimpleType == EdmSimpleTypeKind.Int16.getEdmSimpleTypeInstance()) {
+          return Short.TYPE;
+        }
+        else if (edmSimpleType == EdmSimpleTypeKind.Int32.getEdmSimpleTypeInstance()) {
+          return Integer.TYPE;
+        }
+        else if (edmSimpleType == EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance()) {
+          return Double.TYPE;
+        }
+        else if (edmSimpleType == EdmSimpleTypeKind.Single.getEdmSimpleTypeInstance()) {
+          return Float.TYPE;
+        }
+        else if (edmSimpleType == EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance()) {
+          return BigDecimal.class;
+        }
+        else if (edmSimpleType == EdmSimpleTypeKind.Binary.getEdmSimpleTypeInstance()) {
+          return byte[].class;
+        }
+        else if (edmSimpleType == EdmSimpleTypeKind.Byte.getEdmSimpleTypeInstance()) {
+          return Byte.TYPE;
+        }
+        else if (edmSimpleType == EdmSimpleTypeKind.Boolean.getEdmSimpleTypeInstance()) {
+          return Boolean.TYPE;
+        }
+        else if (edmSimpleType == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()) {
+          return Date.class;
+        }
+        else if (edmSimpleType == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()) {
+          return Calendar.class;
+        }
+        else if (edmSimpleType == EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance()) {
+          return UUID.class;
+        }
+    }
+    throw ODataJPAModelException.throwException(ODataJPAModelException.TYPE_NOT_SUPPORTED.addContent(edmType.toString()), null);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPAEdmMappingModelService.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPAEdmMappingModelService.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPAEdmMappingModelService.java
new file mode 100644
index 0000000..69b94de
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPAEdmMappingModelService.java
@@ -0,0 +1,264 @@
+/*******************************************************************************
+ * 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.access.model;
+
+import java.io.InputStream;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.olingo.odata2.processor.api.jpa.ODataJPAContext;
+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.model.mapping.JPAAttributeMapType.JPAAttribute;
+import org.apache.olingo.odata2.processor.api.jpa.model.mapping.JPAEdmMappingModel;
+import org.apache.olingo.odata2.processor.api.jpa.model.mapping.JPAEmbeddableTypeMapType;
+import org.apache.olingo.odata2.processor.api.jpa.model.mapping.JPAEntityTypeMapType;
+import org.apache.olingo.odata2.processor.api.jpa.model.mapping.JPAPersistenceUnitMapType;
+import org.apache.olingo.odata2.processor.api.jpa.model.mapping.JPARelationshipMapType.JPARelationship;
+
+public class JPAEdmMappingModelService implements JPAEdmMappingModelAccess {
+
+  boolean mappingModelExists = true;
+  private JPAEdmMappingModel mappingModel;
+  private String mappingModelName;
+
+  public JPAEdmMappingModelService(final ODataJPAContext ctx) {
+    mappingModelName = ctx.getJPAEdmMappingModel();
+    if (mappingModelName == null) {
+      mappingModelExists = false;
+    }
+  }
+
+  @Override
+  public void loadMappingModel() {
+
+    if (mappingModelExists) {
+      JAXBContext context;
+      try {
+        context = JAXBContext.newInstance(JPAEdmMappingModel.class);
+
+        Unmarshaller unmarshaller = context.createUnmarshaller();
+        InputStream is = loadMappingModelInputStream();
+        if (is == null) {
+          mappingModelExists = false;
+          return;
+        }
+
+        mappingModel = (JPAEdmMappingModel) unmarshaller.unmarshal(is);
+
+        if (mappingModel != null) {
+          mappingModelExists = true;
+        }
+
+      } catch (JAXBException e) {
+        mappingModelExists = false;
+        ODataJPAModelException.throwException(
+            ODataJPAModelException.GENERAL, e);
+      }
+    }
+  }
+
+  @Override
+  public boolean isMappingModelExists() {
+    return mappingModelExists;
+  }
+
+  @Override
+  public JPAEdmMappingModel getJPAEdmMappingModel() {
+    return mappingModel;
+  }
+
+  @Override
+  public String mapJPAPersistenceUnit(final String persistenceUnitName) {
+
+    JPAPersistenceUnitMapType persistenceUnit = mappingModel
+        .getPersistenceUnit();
+    if (persistenceUnit.getName().equals(persistenceUnitName)) {
+      return persistenceUnit.getEDMSchemaNamespace();
+    }
+
+    return null;
+  }
+
+  @Override
+  public String mapJPAEntityType(final String jpaEntityTypeName) {
+
+    JPAEntityTypeMapType jpaEntityTypeMap = searchJPAEntityTypeMapType(jpaEntityTypeName);
+    if (jpaEntityTypeMap != null) {
+      return jpaEntityTypeMap.getEDMEntityType();
+    } else {
+      return null;
+    }
+  }
+
+  @Override
+  public String mapJPAEntitySet(final String jpaEntityTypeName) {
+    JPAEntityTypeMapType jpaEntityTypeMap = searchJPAEntityTypeMapType(jpaEntityTypeName);
+    if (jpaEntityTypeMap != null) {
+      return jpaEntityTypeMap.getEDMEntitySet();
+    } else {
+      return null;
+    }
+  }
+
+  @Override
+  public String mapJPAAttribute(final String jpaEntityTypeName,
+      final String jpaAttributeName) {
+    JPAEntityTypeMapType jpaEntityTypeMap = searchJPAEntityTypeMapType(jpaEntityTypeName);
+    if (jpaEntityTypeMap != null
+        && jpaEntityTypeMap.getJPAAttributes() != null) {
+      // fixing attributes
+      // removal issue
+      // from mapping
+      for (JPAAttribute jpaAttribute : jpaEntityTypeMap
+          .getJPAAttributes().getJPAAttribute()) {
+        if (jpaAttribute.getName().equals(jpaAttributeName)) {
+          return jpaAttribute.getValue();
+        }
+      }
+    }
+
+    return null;
+  }
+
+  @Override
+  public String mapJPARelationship(final String jpaEntityTypeName,
+      final String jpaRelationshipName) {
+    JPAEntityTypeMapType jpaEntityTypeMap = searchJPAEntityTypeMapType(jpaEntityTypeName);
+    if (jpaEntityTypeMap != null) {
+      for (JPARelationship jpaRealtionship : jpaEntityTypeMap
+          .getJPARelationships().getJPARelationship()) {
+        if (jpaRealtionship.getName().equals(jpaRelationshipName)) {
+          return jpaRealtionship.getValue();
+        }
+      }
+    }
+
+    return null;
+  }
+
+  @Override
+  public String mapJPAEmbeddableType(final String jpaEmbeddableTypeName) {
+    JPAEmbeddableTypeMapType jpaEmbeddableType = searchJPAEmbeddableTypeMapType(jpaEmbeddableTypeName);
+    if (jpaEmbeddableType != null) {
+      return jpaEmbeddableType.getEDMComplexType();
+    } else {
+      return null;
+    }
+  }
+
+  @Override
+  public String mapJPAEmbeddableTypeAttribute(final String jpaEmbeddableTypeName,
+      final String jpaAttributeName) {
+    JPAEmbeddableTypeMapType jpaEmbeddableType = searchJPAEmbeddableTypeMapType(jpaEmbeddableTypeName);
+    if (jpaEmbeddableType != null && jpaEmbeddableType.getJPAAttributes() != null) {
+      for (JPAAttribute jpaAttribute : jpaEmbeddableType
+          .getJPAAttributes().getJPAAttribute()) {
+        if (jpaAttribute.getName().equals(jpaAttributeName)) {
+          return jpaAttribute.getValue();
+        }
+      }
+    }
+    return null;
+  }
+
+  private JPAEntityTypeMapType searchJPAEntityTypeMapType(
+      final String jpaEntityTypeName) {
+    for (JPAEntityTypeMapType jpaEntityType : mappingModel
+        .getPersistenceUnit().getJPAEntityTypes().getJPAEntityType()) {
+      if (jpaEntityType.getName().equals(jpaEntityTypeName)) {
+        return jpaEntityType;
+      }
+    }
+
+    return null;
+  }
+
+  private JPAEmbeddableTypeMapType searchJPAEmbeddableTypeMapType(
+      final String jpaEmbeddableTypeName) {
+    for (JPAEmbeddableTypeMapType jpaEmbeddableType : mappingModel
+        .getPersistenceUnit().getJPAEmbeddableTypes()
+        .getJPAEmbeddableType()) {
+      if (jpaEmbeddableType.getName().equals(jpaEmbeddableTypeName)) {
+        return jpaEmbeddableType;
+      }
+    }
+
+    return null;
+  }
+
+  protected InputStream loadMappingModelInputStream() {
+    InputStream is = JPAEdmMappingModelService.class.getClassLoader()
+        .getResourceAsStream("../../" + mappingModelName);
+
+    return is;
+
+  }
+
+  @Override
+  public boolean checkExclusionOfJPAEntityType(final String jpaEntityTypeName) {
+    JPAEntityTypeMapType type = searchJPAEntityTypeMapType(jpaEntityTypeName);
+    if (type != null) {
+      return type.isExclude();
+    }
+    return false;
+  }
+
+  @Override
+  public boolean checkExclusionOfJPAAttributeType(final String jpaEntityTypeName,
+      final String jpaAttributeName) {
+    JPAEntityTypeMapType type = searchJPAEntityTypeMapType(jpaEntityTypeName);
+    if (type != null && type.getJPAAttributes() != null) {
+      for (JPAAttribute jpaAttribute : type.getJPAAttributes()
+          .getJPAAttribute()) {
+        if (jpaAttribute.getName().equals(jpaAttributeName)) {
+          return jpaAttribute.isExclude();
+        }
+      }
+    }
+    return false;
+  }
+
+  @Override
+  public boolean checkExclusionOfJPAEmbeddableType(
+      final String jpaEmbeddableTypeName) {
+    JPAEmbeddableTypeMapType type = searchJPAEmbeddableTypeMapType(jpaEmbeddableTypeName);
+    if (type != null) {
+      return type.isExclude();
+    }
+    return false;
+  }
+
+  @Override
+  public boolean checkExclusionOfJPAEmbeddableAttributeType(
+      final String jpaEmbeddableTypeName, final String jpaAttributeName) {
+    JPAEmbeddableTypeMapType type = searchJPAEmbeddableTypeMapType(jpaEmbeddableTypeName);
+    if (type != null && type.getJPAAttributes() != null) {
+      for (JPAAttribute jpaAttribute : type.getJPAAttributes()
+          .getJPAAttribute()) {
+        if (jpaAttribute.getName().equals(jpaAttributeName)) {
+          return jpaAttribute.isExclude();
+        }
+      }
+    }
+    return false;
+  }
+}