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:49 UTC

[44/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/exception/ODataJPAMessageServiceDefault.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/exception/ODataJPAMessageServiceDefault.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/exception/ODataJPAMessageServiceDefault.java
new file mode 100644
index 0000000..2039efc
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/exception/ODataJPAMessageServiceDefault.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * 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.exception;
+
+import java.util.Arrays;
+import java.util.Formatter;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingFormatArgumentException;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.apache.olingo.odata2.api.exception.MessageReference;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAMessageService;
+import org.apache.olingo.odata2.processor.core.jpa.ODataJPAContextImpl;
+
+public class ODataJPAMessageServiceDefault implements ODataJPAMessageService {
+
+  private static final String BUNDLE_NAME = "jpaprocessor_msg"; //$NON-NLS-1$
+  private static final Map<Locale, ODataJPAMessageService> LOCALE_2_MESSAGE_SERVICE = new HashMap<Locale, ODataJPAMessageService>();
+  private static final ResourceBundle defaultResourceBundle = ResourceBundle.getBundle(BUNDLE_NAME);
+  private final ResourceBundle resourceBundle;
+  private final Locale lanLocale;
+
+  @Override
+  public String getLocalizedMessage(final MessageReference context, final Throwable exception) {
+
+    Object[] contentAsArray = context.getContent().toArray(new Object[0]);
+
+    if (contentAsArray.length == 0 && exception != null) {
+      contentAsArray = new Object[2];
+      contentAsArray[0] = exception.getStackTrace()[1].getClassName();
+      contentAsArray[1] = exception.getMessage();
+    }
+    String value = null;
+    String key = context.getKey();
+
+    try {
+      value = getMessage(key);
+      StringBuilder builder = new StringBuilder();
+      Formatter f = null;
+      if (lanLocale == null) {
+        f = new Formatter();
+      } else {
+        f = new Formatter(builder, lanLocale);
+      }
+      f.format(value, contentAsArray);
+      f.close();
+      return builder.toString();
+
+    } catch (MissingResourceException e) {
+      return "Missing message for key '" + key + "'!";
+    } catch (MissingFormatArgumentException e) {
+      return "Missing replacement for place holder in value '" + value
+          + "' for following arguments '"
+          + Arrays.toString(contentAsArray) + "'!";
+    }
+  }
+
+  private ODataJPAMessageServiceDefault(final ResourceBundle resourceBundle,
+      final Locale locale) {
+    this.resourceBundle = resourceBundle;
+    lanLocale = locale;
+  }
+
+  public static ODataJPAMessageService getInstance(final Locale locale) {
+
+    Locale acceptedLocale = Locale.ENGLISH;
+    if ((ODataJPAContextImpl.getContextInThreadLocal() != null) && (ODataJPAContextImpl.getContextInThreadLocal().getAcceptableLanguages() != null)) {
+
+      List<Locale> acceptedLanguages = ODataJPAContextImpl.getContextInThreadLocal().getAcceptableLanguages();
+
+      Iterator<Locale> itr = acceptedLanguages.iterator();
+
+      while (itr.hasNext()) {
+
+        Locale tempLocale = itr.next();
+        if (ResourceBundle.getBundle(BUNDLE_NAME, tempLocale).getLocale().equals(tempLocale)) {
+          acceptedLocale = tempLocale;
+          break;
+        }
+      }
+    }
+
+    ODataJPAMessageService messagesInstance = LOCALE_2_MESSAGE_SERVICE
+        .get(acceptedLocale);
+    if (messagesInstance == null) {
+      ResourceBundle resourceBundle = ResourceBundle.getBundle(BUNDLE_NAME, acceptedLocale);
+
+      if (resourceBundle != null) {
+        messagesInstance = new ODataJPAMessageServiceDefault(
+            resourceBundle, acceptedLocale);
+        LOCALE_2_MESSAGE_SERVICE.put(acceptedLocale, messagesInstance);
+      } else if (defaultResourceBundle != null) {
+        messagesInstance = new ODataJPAMessageServiceDefault(
+            defaultResourceBundle, null);
+      }
+
+    }
+    return messagesInstance;
+  }
+
+  private String getMessage(final String key) {
+    return resourceBundle.getString(key);
+  }
+}

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/factory/ODataJPAFactoryImpl.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/factory/ODataJPAFactoryImpl.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/factory/ODataJPAFactoryImpl.java
new file mode 100644
index 0000000..ca843a9
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/factory/ODataJPAFactoryImpl.java
@@ -0,0 +1,246 @@
+/*******************************************************************************
+ * 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.factory;
+
+import java.util.Locale;
+
+import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
+import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
+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.access.JPAMethodContext.JPAMethodContextBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAProcessor;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAMessageService;
+import org.apache.olingo.odata2.processor.api.jpa.factory.JPAAccessFactory;
+import org.apache.olingo.odata2.processor.api.jpa.factory.JPQLBuilderFactory;
+import org.apache.olingo.odata2.processor.api.jpa.factory.ODataJPAAccessFactory;
+import org.apache.olingo.odata2.processor.api.jpa.factory.ODataJPAFactory;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLContext.JPQLContextBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLContextType;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLContextView;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLStatement.JPQLStatementBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmModelView;
+import org.apache.olingo.odata2.processor.core.jpa.ODataJPAContextImpl;
+import org.apache.olingo.odata2.processor.core.jpa.ODataJPAProcessorDefault;
+import org.apache.olingo.odata2.processor.core.jpa.access.data.JPAFunctionContext;
+import org.apache.olingo.odata2.processor.core.jpa.access.data.JPAProcessorImpl;
+import org.apache.olingo.odata2.processor.core.jpa.access.model.JPAEdmMappingModelService;
+import org.apache.olingo.odata2.processor.core.jpa.edm.ODataJPAEdmProvider;
+import org.apache.olingo.odata2.processor.core.jpa.exception.ODataJPAMessageServiceDefault;
+import org.apache.olingo.odata2.processor.core.jpa.jpql.JPQLJoinSelectContext;
+import org.apache.olingo.odata2.processor.core.jpa.jpql.JPQLJoinSelectSingleContext;
+import org.apache.olingo.odata2.processor.core.jpa.jpql.JPQLJoinSelectSingleStatementBuilder;
+import org.apache.olingo.odata2.processor.core.jpa.jpql.JPQLJoinStatementBuilder;
+import org.apache.olingo.odata2.processor.core.jpa.jpql.JPQLSelectContext;
+import org.apache.olingo.odata2.processor.core.jpa.jpql.JPQLSelectSingleContext;
+import org.apache.olingo.odata2.processor.core.jpa.jpql.JPQLSelectSingleStatementBuilder;
+import org.apache.olingo.odata2.processor.core.jpa.jpql.JPQLSelectStatementBuilder;
+import org.apache.olingo.odata2.processor.core.jpa.model.JPAEdmModel;
+
+public class ODataJPAFactoryImpl extends ODataJPAFactory {
+
+  @Override
+  public JPQLBuilderFactory getJPQLBuilderFactory() {
+    return JPQLBuilderFactoryImpl.create();
+  };
+
+  @Override
+  public JPAAccessFactory getJPAAccessFactory() {
+    return JPAAccessFactoryImpl.create();
+  };
+
+  @Override
+  public ODataJPAAccessFactory getODataJPAAccessFactory() {
+    return ODataJPAAccessFactoryImpl.create();
+  };
+
+  private static class JPQLBuilderFactoryImpl implements JPQLBuilderFactory {
+
+    private static JPQLBuilderFactoryImpl factory = null;
+
+    private JPQLBuilderFactoryImpl() {}
+
+    @Override
+    public JPQLStatementBuilder getStatementBuilder(final JPQLContextView context) {
+      JPQLStatementBuilder builder = null;
+      switch (context.getType()) {
+      case SELECT:
+      case SELECT_COUNT: // for $count, Same as select
+        builder = new JPQLSelectStatementBuilder(context);
+        break;
+      case SELECT_SINGLE:
+        builder = new JPQLSelectSingleStatementBuilder(context);
+        break;
+      case JOIN:
+      case JOIN_COUNT: // for $count, Same as join
+        builder = new JPQLJoinStatementBuilder(context);
+        break;
+      case JOIN_SINGLE:
+        builder = new JPQLJoinSelectSingleStatementBuilder(context);
+      default:
+        break;
+      }
+
+      return builder;
+    }
+
+    @Override
+    public JPQLContextBuilder getContextBuilder(final JPQLContextType contextType) {
+      JPQLContextBuilder contextBuilder = null;
+
+      switch (contextType) {
+      case SELECT:
+        JPQLSelectContext selectContext = new JPQLSelectContext(false);
+        contextBuilder = selectContext.new JPQLSelectContextBuilder();
+        break;
+      case SELECT_SINGLE:
+        JPQLSelectSingleContext singleSelectContext = new JPQLSelectSingleContext();
+        contextBuilder = singleSelectContext.new JPQLSelectSingleContextBuilder();
+        break;
+      case JOIN:
+        JPQLJoinSelectContext joinContext = new JPQLJoinSelectContext(
+            false);
+        contextBuilder = joinContext.new JPQLJoinContextBuilder();
+        break;
+      case JOIN_SINGLE:
+        JPQLJoinSelectSingleContext joinSingleContext = new JPQLJoinSelectSingleContext();
+        contextBuilder = joinSingleContext.new JPQLJoinSelectSingleContextBuilder();
+        break;
+      case SELECT_COUNT:
+        JPQLSelectContext selectCountContext = new JPQLSelectContext(
+            true);
+        contextBuilder = selectCountContext.new JPQLSelectContextBuilder();
+        break;
+      case JOIN_COUNT:
+        JPQLJoinSelectContext joinCountContext = new JPQLJoinSelectContext(
+            true);
+        contextBuilder = joinCountContext.new JPQLJoinContextBuilder();
+      default:
+        break;
+      }
+
+      return contextBuilder;
+    }
+
+    private static JPQLBuilderFactory create() {
+      if (factory == null) {
+        return new JPQLBuilderFactoryImpl();
+      } else {
+        return factory;
+      }
+    }
+
+    @Override
+    public JPAMethodContextBuilder getJPAMethodContextBuilder(
+        final JPQLContextType contextType) {
+
+      JPAMethodContextBuilder contextBuilder = null;
+      switch (contextType) {
+      case FUNCTION:
+        JPAFunctionContext methodConext = new JPAFunctionContext();
+        contextBuilder = methodConext.new JPAFunctionContextBuilder();
+
+        break;
+      default:
+        break;
+      }
+      return contextBuilder;
+    }
+
+  }
+
+  private static class ODataJPAAccessFactoryImpl implements
+      ODataJPAAccessFactory {
+
+    private static ODataJPAAccessFactoryImpl factory = null;
+
+    private ODataJPAAccessFactoryImpl() {}
+
+    @Override
+    public ODataSingleProcessor createODataProcessor(
+        final ODataJPAContext oDataJPAContext) {
+      return new ODataJPAProcessorDefault(oDataJPAContext);
+    }
+
+    @Override
+    public EdmProvider createJPAEdmProvider(final ODataJPAContext oDataJPAContext) {
+      return new ODataJPAEdmProvider(oDataJPAContext);
+    }
+
+    @Override
+    public ODataJPAContext createODataJPAContext() {
+      return new ODataJPAContextImpl();
+    }
+
+    private static ODataJPAAccessFactoryImpl create() {
+      if (factory == null) {
+        return new ODataJPAAccessFactoryImpl();
+      } else {
+        return factory;
+      }
+    }
+
+    @Override
+    public ODataJPAMessageService getODataJPAMessageService(final Locale locale) {
+      return ODataJPAMessageServiceDefault.getInstance(locale);
+    }
+
+  }
+
+  private static class JPAAccessFactoryImpl implements JPAAccessFactory {
+
+    private static JPAAccessFactoryImpl factory = null;
+
+    private JPAAccessFactoryImpl() {}
+
+    @Override
+    public JPAEdmModelView getJPAEdmModelView(
+        final ODataJPAContext oDataJPAContext) {
+      JPAEdmModelView view = null;
+
+      view = new JPAEdmModel(oDataJPAContext);
+      return view;
+    }
+
+    @Override
+    public JPAProcessor getJPAProcessor(final ODataJPAContext oDataJPAContext) {
+      JPAProcessor jpaProcessor = new JPAProcessorImpl(oDataJPAContext);
+
+      return jpaProcessor;
+    }
+
+    private static JPAAccessFactoryImpl create() {
+      if (factory == null) {
+        return new JPAAccessFactoryImpl();
+      } else {
+        return factory;
+      }
+    }
+
+    @Override
+    public JPAEdmMappingModelAccess getJPAEdmMappingModelAccess(
+        final ODataJPAContext oDataJPAContext) {
+      JPAEdmMappingModelAccess mappingModelAccess = new JPAEdmMappingModelService(
+          oDataJPAContext);
+
+      return mappingModelAccess;
+    }
+
+  }
+}

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/jpql/JPQLJoinSelectContext.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLJoinSelectContext.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLJoinSelectContext.java
new file mode 100644
index 0000000..c4768fe
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLJoinSelectContext.java
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * 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.jpql;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+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.provider.Mapping;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.uri.NavigationSegment;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAJoinClause;
+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.JPQLJoinContextView;
+import org.apache.olingo.odata2.processor.core.jpa.ODataExpressionParser;
+
+public class JPQLJoinSelectContext extends JPQLSelectContext implements
+    JPQLJoinContextView {
+
+  private List<JPAJoinClause> jpaJoinClauses = null;
+
+  protected void setJPAOuterJoinClause(final List<JPAJoinClause> jpaOuterJoinClauses) {
+    jpaJoinClauses = jpaOuterJoinClauses;
+  }
+
+  public JPQLJoinSelectContext(final boolean isCountOnly) {
+    super(isCountOnly);
+  }
+
+  public class JPQLJoinContextBuilder extends JPQLSelectContextBuilder {
+
+    protected int relationShipAliasCounter = 0;
+
+    @Override
+    public JPQLContext build() throws ODataJPAModelException,
+        ODataJPARuntimeException {
+      try {
+
+        if (JPQLJoinSelectContext.this.isCountOnly) {
+          setType(JPQLContextType.JOIN_COUNT);
+        } else {
+          setType(JPQLContextType.JOIN);
+        }
+
+        setJPAOuterJoinClause(generateJoinClauses());
+
+        if (!jpaJoinClauses.isEmpty()) {
+          JPAJoinClause joinClause = jpaJoinClauses
+              .get(jpaJoinClauses.size() - 1);
+          setJPAEntityName(joinClause
+              .getEntityName());
+          setJPAEntityAlias(joinClause
+              .getEntityRelationShipAlias());
+        }
+
+        setOrderByCollection(generateOrderByFileds());
+
+        setSelectExpression(generateSelectExpression());
+
+        setWhereExpression(generateWhereExpression());
+
+      } catch (ODataException e) {
+        throw ODataJPARuntimeException.throwException(
+            ODataJPARuntimeException.INNER_EXCEPTION, e);
+      }
+
+      return JPQLJoinSelectContext.this;
+    }
+
+    protected List<JPAJoinClause> generateJoinClauses()
+        throws ODataJPARuntimeException, EdmException {
+
+      List<JPAJoinClause> jpaOuterJoinClauses = new ArrayList<JPAJoinClause>();
+      JPAJoinClause jpaOuterJoinClause = null;
+      String joinCondition = null;
+      String entityAlias = generateJPAEntityAlias();
+      joinCondition = ODataExpressionParser.parseKeyPredicates(
+          entitySetView.getKeyPredicates(),
+          entityAlias);
+
+      EdmEntityType entityType = entitySetView.getStartEntitySet()
+          .getEntityType();
+      Mapping mapping = (Mapping) entityType.getMapping();
+      String entityTypeName = null;
+      if (mapping != null) {
+        entityTypeName = mapping.getInternalName();
+      } else {
+        entityTypeName = entityType.getName();
+      }
+
+      jpaOuterJoinClause = new JPAJoinClause(
+          entityTypeName,
+          entityAlias,
+          null,
+          null, joinCondition,
+          JPAJoinClause.JOIN.INNER);
+
+      jpaOuterJoinClauses.add(jpaOuterJoinClause);
+
+      for (NavigationSegment navigationSegment : entitySetView
+          .getNavigationSegments()) {
+
+        EdmNavigationProperty navigationProperty = navigationSegment
+            .getNavigationProperty();
+
+        String relationShipAlias = generateRelationShipAlias();
+
+        joinCondition = ODataExpressionParser.parseKeyPredicates(
+            navigationSegment.getKeyPredicates(),
+            relationShipAlias);
+
+        jpaOuterJoinClause = new JPAJoinClause(
+            getFromEntityName(navigationProperty),
+            entityAlias,
+            getRelationShipName(navigationProperty),
+            relationShipAlias, joinCondition,
+            JPAJoinClause.JOIN.INNER);
+
+        jpaOuterJoinClauses.add(jpaOuterJoinClause);
+
+      }
+
+      return jpaOuterJoinClauses;
+    }
+
+    private String getFromEntityName(
+        final EdmNavigationProperty navigationProperty) throws EdmException {
+
+      String fromRole = navigationProperty.getFromRole();
+
+      EdmEntityType toEntityType = navigationProperty.getRelationship()
+          .getEnd(fromRole).getEntityType();
+
+      EdmMapping mapping = toEntityType.getMapping();
+
+      String entityName = null;
+      if (mapping != null) {
+        entityName = mapping.getInternalName();
+      } else {
+        entityName = toEntityType.getName();
+      }
+
+      return entityName;
+
+    }
+
+    private String getRelationShipName(
+        final EdmNavigationProperty navigationProperty) throws EdmException {
+
+      EdmMapping mapping = navigationProperty.getMapping();
+
+      String relationShipName = null;
+      if (mapping != null) {
+        relationShipName = mapping.getInternalName();
+      } else {
+        relationShipName = navigationProperty.getName();
+      }
+
+      return relationShipName;
+    }
+
+    private String generateRelationShipAlias() {
+      return new String("R" + ++relationShipAliasCounter);
+    }
+  }
+
+  @Override
+  public List<JPAJoinClause> getJPAJoinClauses() {
+    return jpaJoinClauses;
+  }
+
+}

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/jpql/JPQLJoinSelectSingleContext.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLJoinSelectSingleContext.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLJoinSelectSingleContext.java
new file mode 100644
index 0000000..3f504c1
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLJoinSelectSingleContext.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * 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.jpql;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+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.provider.Mapping;
+import org.apache.olingo.odata2.api.uri.NavigationSegment;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAJoinClause;
+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.JPQLJoinSelectSingleContextView;
+import org.apache.olingo.odata2.processor.core.jpa.ODataExpressionParser;
+
+public class JPQLJoinSelectSingleContext extends JPQLSelectSingleContext
+    implements JPQLJoinSelectSingleContextView {
+
+  private List<JPAJoinClause> jpaJoinClauses = null;
+
+  protected void setJPAJoinClause(final List<JPAJoinClause> jpaJoinClauses) {
+    this.jpaJoinClauses = jpaJoinClauses;
+  }
+
+  public class JPQLJoinSelectSingleContextBuilder extends
+      JPQLSelectSingleContextBuilder {
+
+    protected int relationShipAliasCounter = 0;
+
+    @Override
+    public JPQLContext build() throws ODataJPAModelException,
+        ODataJPARuntimeException {
+      try {
+        setType(JPQLContextType.JOIN_SINGLE);
+        setJPAJoinClause(generateJoinClauses());
+
+        if (!jpaJoinClauses.isEmpty()) {
+          JPAJoinClause joinClause = jpaJoinClauses
+              .get(jpaJoinClauses.size() - 1);
+          setJPAEntityName(joinClause.getEntityName());
+          setJPAEntityAlias(joinClause
+              .getEntityRelationShipAlias());
+        }
+
+        setKeyPredicates(entityView
+            .getKeyPredicates());
+
+        setSelectExpression(generateSelectExpression());
+
+      } catch (EdmException e) {
+        throw ODataJPARuntimeException.throwException(
+            ODataJPARuntimeException.GENERAL, e);
+      }
+
+      return JPQLJoinSelectSingleContext.this;
+    }
+
+    protected List<JPAJoinClause> generateJoinClauses()
+        throws ODataJPARuntimeException, EdmException {
+
+      List<JPAJoinClause> jpaOuterJoinClauses = new ArrayList<JPAJoinClause>();
+      JPAJoinClause jpaOuterJoinClause = null;
+      String joinCondition = null;
+      String entityAlias = generateJPAEntityAlias();
+      joinCondition = ODataExpressionParser.parseKeyPredicates(
+          entityView.getKeyPredicates(), entityAlias);
+
+      EdmEntityType entityType = entityView.getStartEntitySet()
+          .getEntityType();
+      Mapping mapping = (Mapping) entityType.getMapping();
+      String entityTypeName = null;
+      if (mapping != null) {
+        entityTypeName = mapping.getInternalName();
+      } else {
+        entityTypeName = entityType.getName();
+      }
+
+      jpaOuterJoinClause = new JPAJoinClause(entityTypeName, entityAlias,
+          null, null, joinCondition, JPAJoinClause.JOIN.INNER);
+
+      jpaOuterJoinClauses.add(jpaOuterJoinClause);
+
+      for (NavigationSegment navigationSegment : entityView
+          .getNavigationSegments()) {
+
+        EdmNavigationProperty navigationProperty = navigationSegment
+            .getNavigationProperty();
+
+        String relationShipAlias = generateRelationShipAlias();
+
+        joinCondition = ODataExpressionParser
+            .parseKeyPredicates(
+                navigationSegment.getKeyPredicates(),
+                relationShipAlias);
+
+        jpaOuterJoinClause = new JPAJoinClause(
+            getFromEntityName(navigationProperty), entityAlias,
+            getRelationShipName(navigationProperty),
+            relationShipAlias, joinCondition,
+            JPAJoinClause.JOIN.INNER);
+
+        jpaOuterJoinClauses.add(jpaOuterJoinClause);
+
+      }
+
+      return jpaOuterJoinClauses;
+    }
+
+    private String getFromEntityName(
+        final EdmNavigationProperty navigationProperty) throws EdmException {
+
+      String fromRole = navigationProperty.getFromRole();
+
+      EdmEntityType fromEntityType = navigationProperty.getRelationship()
+          .getEnd(fromRole).getEntityType();
+
+      EdmMapping mapping = fromEntityType.getMapping();
+
+      String entityName = null;
+      if (mapping != null) {
+        entityName = mapping.getInternalName();
+      } else {
+        entityName = fromEntityType.getName();
+      }
+
+      return entityName;
+
+    }
+
+    private String getRelationShipName(
+        final EdmNavigationProperty navigationProperty) throws EdmException {
+
+      EdmMapping mapping = navigationProperty.getMapping();
+
+      String relationShipName = null;
+      if (mapping != null) {
+        relationShipName = mapping.getInternalName();
+      } else {
+        relationShipName = navigationProperty.getName();
+      }
+
+      return relationShipName;
+    }
+
+    private String generateRelationShipAlias() {
+      return new String("R" + ++relationShipAliasCounter);
+    }
+  }
+
+  @Override
+  public List<JPAJoinClause> getJPAJoinClauses() {
+    return jpaJoinClauses;
+  }
+
+}

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/jpql/JPQLJoinSelectSingleStatementBuilder.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLJoinSelectSingleStatementBuilder.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLJoinSelectSingleStatementBuilder.java
new file mode 100644
index 0000000..1e7d6f0
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLJoinSelectSingleStatementBuilder.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *        or more contributor license agreements.  See the NOTICE file
+ *        distributed with this work for additional information
+ *        regarding copyright ownership.  The ASF licenses this file
+ *        to you under the Apache License, Version 2.0 (the
+ *        "License"); you may not use this file except in compliance
+ *        with the License.  You may obtain a copy of the License at
+ * 
+ *          http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *        Unless required by applicable law or agreed to in writing,
+ *        software distributed under the License is distributed on an
+ *        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *        KIND, either express or implied.  See the License for the
+ *        specific language governing permissions and limitations
+ *        under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.processor.core.jpa.jpql;
+
+import java.util.List;
+
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAJoinClause;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLContextView;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLJoinSelectSingleContextView;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLStatement;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLStatement.JPQLStatementBuilder;
+
+public class JPQLJoinSelectSingleStatementBuilder extends JPQLStatementBuilder {
+
+  JPQLStatement jpqlStatement;
+  private JPQLJoinSelectSingleContextView context;
+
+  public JPQLJoinSelectSingleStatementBuilder(final JPQLContextView context) {
+    this.context = (JPQLJoinSelectSingleContextView) context;
+  }
+
+  @Override
+  public JPQLStatement build() throws ODataJPARuntimeException {
+    jpqlStatement = createStatement(createJPQLQuery());
+    return jpqlStatement;
+
+  }
+
+  private String createJPQLQuery() throws ODataJPARuntimeException {
+
+    StringBuilder jpqlQuery = new StringBuilder();
+    StringBuilder joinWhereCondition = null;
+
+    jpqlQuery.append(JPQLStatement.KEYWORD.SELECT).append(
+        JPQLStatement.DELIMITER.SPACE);
+    jpqlQuery.append(context.getSelectExpression()).append(JPQLStatement.DELIMITER.SPACE);
+    jpqlQuery.append(JPQLStatement.KEYWORD.FROM).append(
+        JPQLStatement.DELIMITER.SPACE);
+
+    if (context.getJPAJoinClauses() != null
+        && context.getJPAJoinClauses().size() > 0) {
+      List<JPAJoinClause> joinClauseList = context.getJPAJoinClauses();
+      JPAJoinClause joinClause = joinClauseList.get(0);
+      String joinCondition = joinClause.getJoinCondition();
+      joinWhereCondition = new StringBuilder();
+      if (joinCondition != null) {
+        joinWhereCondition.append(joinCondition);
+      }
+      String relationShipAlias = null;
+      joinClause = joinClauseList.get(1);
+      jpqlQuery.append(joinClause.getEntityName()).append(
+          JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(joinClause.getEntityAlias());
+
+      int i = 1;
+      int limit = joinClauseList.size();
+      relationShipAlias = joinClause.getEntityAlias();
+      while (i < limit) {
+        jpqlQuery.append(JPQLStatement.DELIMITER.SPACE);
+        jpqlQuery.append(JPQLStatement.KEYWORD.JOIN).append(
+            JPQLStatement.DELIMITER.SPACE);
+
+        joinClause = joinClauseList.get(i);
+        jpqlQuery.append(relationShipAlias).append(
+            JPQLStatement.DELIMITER.PERIOD);
+        jpqlQuery.append(joinClause.getEntityRelationShip()).append(
+            JPQLStatement.DELIMITER.SPACE);
+        jpqlQuery.append(joinClause.getEntityRelationShipAlias());
+
+        relationShipAlias = joinClause.getEntityRelationShipAlias();
+        i++;
+
+        joinCondition = joinClause.getJoinCondition();
+        if (joinCondition != null) {
+          joinWhereCondition.append(JPQLStatement.DELIMITER.SPACE
+              + JPQLStatement.Operator.AND
+              + JPQLStatement.DELIMITER.SPACE);
+
+          joinWhereCondition.append(joinCondition);
+        }
+
+      }
+    } else {
+      throw ODataJPARuntimeException.throwException(
+          ODataJPARuntimeException.JOIN_CLAUSE_EXPECTED, null);
+    }
+
+    if (joinWhereCondition.length() > 0) {
+      jpqlQuery.append(JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(JPQLStatement.KEYWORD.WHERE).append(JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(joinWhereCondition.toString());
+    }
+
+    return jpqlQuery.toString();
+
+  }
+
+}

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/jpql/JPQLJoinStatementBuilder.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLJoinStatementBuilder.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLJoinStatementBuilder.java
new file mode 100644
index 0000000..336dd9b
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLJoinStatementBuilder.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * 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.jpql;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAJoinClause;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLContextType;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLContextView;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLJoinContextView;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLStatement;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLStatement.JPQLStatementBuilder;
+
+public class JPQLJoinStatementBuilder extends JPQLStatementBuilder {
+
+  JPQLStatement jpqlStatement;
+  private JPQLJoinContextView context;
+
+  public JPQLJoinStatementBuilder(final JPQLContextView context) {
+    this.context = (JPQLJoinContextView) context;
+  }
+
+  @Override
+  public JPQLStatement build() throws ODataJPARuntimeException {
+    jpqlStatement = createStatement(createJPQLQuery());
+    return jpqlStatement;
+
+  }
+
+  private String createJPQLQuery() throws ODataJPARuntimeException {
+
+    StringBuilder jpqlQuery = new StringBuilder();
+    StringBuilder joinWhereCondition = null;
+
+    jpqlQuery.append(JPQLStatement.KEYWORD.SELECT).append(JPQLStatement.DELIMITER.SPACE);
+    if (context.getType().equals(JPQLContextType.JOIN_COUNT)) {//$COUNT
+      jpqlQuery.append(JPQLStatement.KEYWORD.COUNT).append(JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(JPQLStatement.DELIMITER.PARENTHESIS_LEFT).append(JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(context.getSelectExpression()).append(JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(JPQLStatement.DELIMITER.PARENTHESIS_RIGHT).append(JPQLStatement.DELIMITER.SPACE);
+    } else { //Normal
+      jpqlQuery.append(context.getSelectExpression()).append(JPQLStatement.DELIMITER.SPACE);
+    }
+
+    jpqlQuery.append(JPQLStatement.KEYWORD.FROM).append(
+        JPQLStatement.DELIMITER.SPACE);
+
+    if (context.getJPAJoinClauses() != null
+        && context.getJPAJoinClauses().size() > 0) {
+      List<JPAJoinClause> joinClauseList = context.getJPAJoinClauses();
+      JPAJoinClause joinClause = joinClauseList.get(0);
+      String joinCondition = joinClause.getJoinCondition();
+      joinWhereCondition = new StringBuilder();
+      if (joinCondition != null) {
+        joinWhereCondition.append(joinCondition);
+      }
+      String relationShipAlias = null;
+      joinClause = joinClauseList.get(1);
+      jpqlQuery.append(joinClause.getEntityName()).append(
+          JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(joinClause.getEntityAlias());
+
+      int i = 1;
+      int limit = joinClauseList.size();
+      relationShipAlias = joinClause.getEntityAlias();
+      while (i < limit) {
+        jpqlQuery.append(JPQLStatement.DELIMITER.SPACE);
+        jpqlQuery.append(JPQLStatement.KEYWORD.JOIN).append(
+            JPQLStatement.DELIMITER.SPACE);
+
+        joinClause = joinClauseList.get(i);
+        jpqlQuery.append(relationShipAlias).append(
+            JPQLStatement.DELIMITER.PERIOD);
+        jpqlQuery.append(joinClause.getEntityRelationShip()).append(
+            JPQLStatement.DELIMITER.SPACE);
+        jpqlQuery.append(joinClause.getEntityRelationShipAlias());
+
+        relationShipAlias = joinClause.getEntityRelationShipAlias();
+        i++;
+
+        joinCondition = joinClause.getJoinCondition();
+        if (joinCondition != null) {
+          joinWhereCondition.append(JPQLStatement.DELIMITER.SPACE
+              + JPQLStatement.Operator.AND
+              + JPQLStatement.DELIMITER.SPACE);
+
+          joinWhereCondition.append(joinCondition);
+        }
+      }
+    } else {
+      throw ODataJPARuntimeException.throwException(
+          ODataJPARuntimeException.JOIN_CLAUSE_EXPECTED, null);
+    }
+    String whereExpression = context.getWhereExpression();
+    if (whereExpression != null || joinWhereCondition.length() > 0) {
+      jpqlQuery.append(JPQLStatement.DELIMITER.SPACE).append(JPQLStatement.KEYWORD.WHERE).append(
+          JPQLStatement.DELIMITER.SPACE);
+      if (whereExpression != null) {
+        jpqlQuery.append(whereExpression);
+        if (joinWhereCondition != null) {
+          jpqlQuery.append(JPQLStatement.DELIMITER.SPACE
+              + JPQLStatement.Operator.AND
+              + JPQLStatement.DELIMITER.SPACE);
+        }
+      }
+      if (joinWhereCondition != null) {
+        jpqlQuery.append(joinWhereCondition.toString());
+      }
+
+    }
+
+    if (context.getOrderByCollection() != null
+        && context.getOrderByCollection().size() > 0) {
+
+      StringBuilder orderByBuilder = new StringBuilder();
+      Iterator<Entry<String, String>> orderItr = context
+          .getOrderByCollection().entrySet().iterator();
+
+      int i = 0;
+
+      while (orderItr.hasNext()) {
+        if (i != 0) {
+          orderByBuilder.append(JPQLStatement.DELIMITER.SPACE).append(JPQLStatement.DELIMITER.COMMA)
+              .append(JPQLStatement.DELIMITER.SPACE);
+        }
+        Entry<String, String> entry = orderItr.next();
+        orderByBuilder.append(entry.getKey())
+            .append(JPQLStatement.DELIMITER.SPACE);
+        orderByBuilder.append(entry.getValue());
+        i++;
+      }
+      jpqlQuery.append(JPQLStatement.DELIMITER.SPACE).append(JPQLStatement.KEYWORD.ORDERBY).append(
+          JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(orderByBuilder);
+    }
+
+    return jpqlQuery.toString();
+  }
+}

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/jpql/JPQLSelectContext.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLSelectContext.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLSelectContext.java
new file mode 100644
index 0000000..61cd133
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLSelectContext.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * 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.jpql;
+
+import java.util.HashMap;
+
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+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.JPQLSelectContextView;
+import org.apache.olingo.odata2.processor.core.jpa.ODataExpressionParser;
+
+public class JPQLSelectContext extends JPQLContext implements
+    JPQLSelectContextView {
+
+  protected String selectExpression;
+  protected HashMap<String, String> orderByCollection;
+  protected String whereCondition;
+
+  protected boolean isCountOnly = false;//Support for $count
+
+  public JPQLSelectContext(final boolean isCountOnly) {
+    this.isCountOnly = isCountOnly;
+  }
+
+  protected final void setOrderByCollection(
+      final HashMap<String, String> orderByCollection) {
+    this.orderByCollection = orderByCollection;
+  }
+
+  protected final void setWhereExpression(final String filterExpression) {
+    whereCondition = filterExpression;
+  }
+
+  protected final void setSelectExpression(final String selectExpression) {
+    this.selectExpression = selectExpression;
+  }
+
+  @Override
+  public String getSelectExpression() {
+    return selectExpression;
+  }
+
+  @Override
+  public HashMap<String, String> getOrderByCollection() {
+    return orderByCollection;
+  }
+
+  @Override
+  public String getWhereExpression() {
+    return whereCondition;
+  }
+
+  public class JPQLSelectContextBuilder
+      extends
+      org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLContext.JPQLContextBuilder {
+
+    protected GetEntitySetUriInfo entitySetView;
+
+    @Override
+    public JPQLContext build() throws ODataJPAModelException,
+        ODataJPARuntimeException {
+      if (entitySetView != null) {
+
+        try {
+
+          if (isCountOnly) {
+            setType(JPQLContextType.SELECT_COUNT);
+          } else {
+            setType(JPQLContextType.SELECT);
+          }
+          EdmEntityType entityType = entitySetView
+              .getTargetEntitySet().getEntityType();
+          EdmMapping mapping = entityType.getMapping();
+          if (mapping != null) {
+            setJPAEntityName(mapping.getInternalName());
+          } else {
+            setJPAEntityName(entityType.getName());
+          }
+
+          setJPAEntityAlias(generateJPAEntityAlias());
+
+          setOrderByCollection(generateOrderByFileds());
+
+          setSelectExpression(generateSelectExpression());
+
+          setWhereExpression(generateWhereExpression());
+        } catch (ODataException e) {
+          throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
+        }
+      }
+
+      return JPQLSelectContext.this;
+
+    }
+
+    @Override
+    protected void setResultsView(final Object resultsView) {
+      if (resultsView instanceof GetEntitySetUriInfo) {
+        entitySetView = (GetEntitySetUriInfo) resultsView;
+      }
+
+    }
+
+    /*
+     * Generate Select Clause 
+     */
+    protected String generateSelectExpression() throws EdmException {
+      return getJPAEntityAlias();
+    }
+
+    /*
+     * Generate Order By Clause Fields
+     */
+    protected HashMap<String, String> generateOrderByFileds()
+        throws ODataJPARuntimeException, EdmException {
+
+      if (entitySetView.getOrderBy() != null) {
+
+        return ODataExpressionParser
+            .parseToJPAOrderByExpression(entitySetView.getOrderBy(), getJPAEntityAlias());
+
+      } else if (entitySetView.getTop() != null
+          || entitySetView.getSkip() != null) {
+
+        return ODataExpressionParser
+            .parseKeyPropertiesToJPAOrderByExpression(entitySetView.getTargetEntitySet()
+                .getEntityType().getKeyProperties(), getJPAEntityAlias());
+      } else {
+        return null;
+      }
+
+    }
+
+    /*
+     * Generate Where Clause Expression
+     */
+    protected String generateWhereExpression() throws ODataException {
+      if (entitySetView.getFilter() != null) {
+        return ODataExpressionParser
+            .parseToJPAWhereExpression(entitySetView.getFilter(), getJPAEntityAlias());
+      }
+      return 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/jpql/JPQLSelectSingleContext.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLSelectSingleContext.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLSelectSingleContext.java
new file mode 100644
index 0000000..f2ddcef
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLSelectSingleContext.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * 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.jpql;
+
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.uri.KeyPredicate;
+import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
+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.JPQLSelectSingleContextView;
+
+public class JPQLSelectSingleContext extends JPQLContext implements JPQLSelectSingleContextView {
+
+  private String selectExpression;
+  private List<KeyPredicate> keyPredicates;
+
+  protected void setKeyPredicates(final List<KeyPredicate> keyPredicates) {
+    this.keyPredicates = keyPredicates;
+  }
+
+  @Override
+  public List<KeyPredicate> getKeyPredicates() {
+    return keyPredicates;
+  }
+
+  protected final void setSelectExpression(final String selectExpression) {
+    this.selectExpression = selectExpression;
+  }
+
+  @Override
+  public String getSelectExpression() {
+    return selectExpression;
+  }
+
+  public class JPQLSelectSingleContextBuilder
+      extends
+      org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLContext.JPQLContextBuilder {
+
+    protected GetEntityUriInfo entityView;
+
+    @Override
+    public JPQLContext build() throws ODataJPAModelException, ODataJPARuntimeException {
+      if (entityView != null) {
+
+        try {
+
+          setType(JPQLContextType.SELECT_SINGLE);
+
+          EdmEntityType entityType = entityView
+              .getTargetEntitySet().getEntityType();
+          EdmMapping mapping = entityType.getMapping();
+          if (mapping != null) {
+            setJPAEntityName(mapping.getInternalName());
+          } else {
+            setJPAEntityName(entityType.getName());
+          }
+
+          setJPAEntityAlias(generateJPAEntityAlias());
+
+          setKeyPredicates(entityView.getKeyPredicates());
+
+          setSelectExpression(generateSelectExpression());
+
+        } catch (EdmException e) {
+          throw ODataJPARuntimeException.throwException(
+              ODataJPARuntimeException.GENERAL.addContent(e
+                  .getMessage()), e);
+        }
+
+      }
+
+      return JPQLSelectSingleContext.this;
+
+    }
+
+    @Override
+    protected void setResultsView(final Object resultsView) {
+      if (resultsView instanceof GetEntityUriInfo) {
+        entityView = (GetEntityUriInfo) resultsView;
+      }
+
+    }
+
+    /*
+     * Generate Select Clause 
+     */
+    protected String generateSelectExpression() throws EdmException {
+      return getJPAEntityAlias();
+    }
+  }
+}

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/jpql/JPQLSelectSingleStatementBuilder.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLSelectSingleStatementBuilder.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLSelectSingleStatementBuilder.java
new file mode 100644
index 0000000..7ffa49f
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLSelectSingleStatementBuilder.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * 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.jpql;
+
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLContextView;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLSelectSingleContextView;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLStatement;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLStatement.JPQLStatementBuilder;
+import org.apache.olingo.odata2.processor.core.jpa.ODataExpressionParser;
+
+public class JPQLSelectSingleStatementBuilder extends JPQLStatementBuilder {
+
+  JPQLStatement jpqlStatement;
+  private JPQLSelectSingleContextView context;
+
+  public JPQLSelectSingleStatementBuilder(final JPQLContextView context) {
+    this.context = (JPQLSelectSingleContextView) context;
+  }
+
+  @Override
+  public JPQLStatement build() throws ODataJPARuntimeException {
+    jpqlStatement = createStatement(createJPQLQuery());
+    return jpqlStatement;
+
+  }
+
+  private String createJPQLQuery() throws ODataJPARuntimeException {
+
+    StringBuilder jpqlQuery = new StringBuilder();
+    String tableAlias = context.getJPAEntityAlias();
+    String fromClause = context.getJPAEntityName()
+        + JPQLStatement.DELIMITER.SPACE + tableAlias;
+
+    jpqlQuery.append(JPQLStatement.KEYWORD.SELECT).append(
+        JPQLStatement.DELIMITER.SPACE);
+    jpqlQuery.append(context.getSelectExpression()).append(JPQLStatement.DELIMITER.SPACE);
+    jpqlQuery.append(JPQLStatement.KEYWORD.FROM).append(JPQLStatement.DELIMITER.SPACE);
+    jpqlQuery.append(fromClause);
+
+    if (context.getKeyPredicates() != null
+        && context.getKeyPredicates().size() > 0) {
+      jpqlQuery.append(JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(JPQLStatement.KEYWORD.WHERE).append(JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(ODataExpressionParser.parseKeyPredicates(context.getKeyPredicates(),
+          context.getJPAEntityAlias()));
+    }
+
+    return jpqlQuery.toString();
+
+  }
+
+}

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/jpql/JPQLSelectStatementBuilder.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLSelectStatementBuilder.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLSelectStatementBuilder.java
new file mode 100644
index 0000000..8fc2792
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/jpql/JPQLSelectStatementBuilder.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * 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.jpql;
+
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLContextType;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLContextView;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLSelectContextView;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLStatement;
+import org.apache.olingo.odata2.processor.api.jpa.jpql.JPQLStatement.JPQLStatementBuilder;
+
+public class JPQLSelectStatementBuilder extends JPQLStatementBuilder {
+
+  JPQLStatement jpqlStatement;
+  private JPQLSelectContextView context;
+
+  public JPQLSelectStatementBuilder(final JPQLContextView context) {
+    this.context = (JPQLSelectContextView) context;
+  }
+
+  @Override
+  public JPQLStatement build() throws ODataJPARuntimeException {
+    jpqlStatement = createStatement(createJPQLQuery());
+    return jpqlStatement;
+
+  }
+
+  private String createJPQLQuery() throws ODataJPARuntimeException {
+
+    StringBuilder jpqlQuery = new StringBuilder();
+    String tableAlias = context.getJPAEntityAlias();
+    String fromClause = context.getJPAEntityName() + JPQLStatement.DELIMITER.SPACE + tableAlias;
+
+    jpqlQuery.append(JPQLStatement.KEYWORD.SELECT).append(JPQLStatement.DELIMITER.SPACE);
+    if (context.getType().equals(JPQLContextType.SELECT_COUNT)) { //$COUNT
+      jpqlQuery.append(JPQLStatement.KEYWORD.COUNT).append(JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(JPQLStatement.DELIMITER.PARENTHESIS_LEFT).append(JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(context.getSelectExpression()).append(JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(JPQLStatement.DELIMITER.PARENTHESIS_RIGHT).append(JPQLStatement.DELIMITER.SPACE);
+    } else {//Normal
+      jpqlQuery.append(context.getSelectExpression()).append(JPQLStatement.DELIMITER.SPACE);
+    }
+
+    jpqlQuery.append(JPQLStatement.KEYWORD.FROM).append(JPQLStatement.DELIMITER.SPACE);
+    jpqlQuery.append(fromClause);
+
+    if (context.getWhereExpression() != null) {
+      jpqlQuery.append(JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(JPQLStatement.KEYWORD.WHERE).append(JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(context.getWhereExpression());
+    }
+
+    if (context.getOrderByCollection() != null
+        && context.getOrderByCollection().size() > 0) {
+
+      StringBuilder orderByBuilder = new StringBuilder();
+      Iterator<Entry<String, String>> orderItr = context
+          .getOrderByCollection().entrySet().iterator();
+
+      int i = 0;
+
+      while (orderItr.hasNext()) {
+        if (i != 0) {
+          orderByBuilder.append(JPQLStatement.DELIMITER.SPACE).append(JPQLStatement.DELIMITER.COMMA).append(JPQLStatement.DELIMITER.SPACE);
+        }
+        Entry<String, String> entry = orderItr.next();
+        orderByBuilder.append(entry.getKey()).append(JPQLStatement.DELIMITER.SPACE);
+        orderByBuilder.append(entry.getValue());
+        i++;
+      }
+      jpqlQuery.append(JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(JPQLStatement.KEYWORD.ORDERBY).append(JPQLStatement.DELIMITER.SPACE);
+      jpqlQuery.append(orderByBuilder);
+    }
+
+    return jpqlQuery.toString();
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmAssociation.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmAssociation.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmAssociation.java
new file mode 100644
index 0000000..0f6e1ec
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmAssociation.java
@@ -0,0 +1,270 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *        or more contributor license agreements.  See the NOTICE file
+ *        distributed with this work for additional information
+ *        regarding copyright ownership.  The ASF licenses this file
+ *        to you under the Apache License, Version 2.0 (the
+ *        "License"); you may not use this file except in compliance
+ *        with the License.  You may obtain a copy of the License at
+ * 
+ *          http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *        Unless required by applicable law or agreed to in writing,
+ *        software distributed under the License is distributed on an
+ *        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *        KIND, either express or implied.  See the License for the
+ *        specific language governing permissions and limitations
+ *        under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.processor.core.jpa.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.provider.Association;
+import org.apache.olingo.odata2.api.edm.provider.AssociationEnd;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmAssociationEndView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmAssociationView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntityTypeView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmPropertyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmReferentialConstraintView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmSchemaView;
+import org.apache.olingo.odata2.processor.core.jpa.access.model.JPAEdmNameBuilder;
+
+public class JPAEdmAssociation extends JPAEdmBaseViewImpl implements
+    JPAEdmAssociationView {
+
+  private JPAEdmAssociationEndView associationEndView;
+
+  private Association currentAssociation;
+  private List<Association> consistentAssociatonList;
+  private HashMap<String, Association> associationMap;
+  private HashMap<String, JPAEdmAssociationEndView> associationEndMap;
+  private List<JPAEdmReferentialConstraintView> inconsistentRefConstraintViewList;
+  private int numberOfSimilarEndPoints;
+
+  public JPAEdmAssociation(final JPAEdmAssociationEndView associationEndview,
+      final JPAEdmEntityTypeView entityTypeView,
+      final JPAEdmPropertyView propertyView, final int value) {
+    super(associationEndview);
+    associationEndView = associationEndview;
+    numberOfSimilarEndPoints = value;
+    init();
+  }
+
+  public JPAEdmAssociation(final JPAEdmSchemaView view) {
+    super(view);
+    init();
+  }
+
+  private void init() {
+    isConsistent = false;
+    consistentAssociatonList = new ArrayList<Association>();
+    inconsistentRefConstraintViewList = new LinkedList<JPAEdmReferentialConstraintView>();
+    associationMap = new HashMap<String, Association>();
+    associationEndMap = new HashMap<String, JPAEdmAssociationEndView>();
+  }
+
+  @Override
+  public JPAEdmBuilder getBuilder() {
+    if (builder == null) {
+      builder = new JPAEdmAssociationBuilder();
+    }
+    return builder;
+  }
+
+  @Override
+  public Association getEdmAssociation() {
+    return currentAssociation;
+  }
+
+  @Override
+  public List<Association> getConsistentEdmAssociationList() {
+    return consistentAssociatonList;
+  }
+
+  @Override
+  public Association searchAssociation(final JPAEdmAssociationEndView view) {
+    if (view != null) {
+      for (String key : associationMap.keySet()) {
+        Association association = associationMap.get(key);
+        if (association != null) {
+          if (view.compare(association.getEnd1(),
+              association.getEnd2())) {
+            JPAEdmAssociationEndView associationEnd = associationEndMap
+                .get(association.getName());
+            if (associationEnd.getJoinColumnName() != null
+                && associationEnd
+                    .getJoinColumnReferenceColumnName() != null
+                && view.getJoinColumnName() != null
+                && view.getJoinColumnReferenceColumnName() != null) {
+              if (view.getJoinColumnName().equals(
+                  associationEnd.getJoinColumnName())
+                  && view.getJoinColumnReferenceColumnName()
+                      .equals(associationEnd
+                          .getJoinColumnReferenceColumnName())) {
+                currentAssociation = association;
+                return association;
+              }
+
+            }
+            if (associationEnd.getMappedByName() != null) {
+              if (associationEnd.getMappedByName().equals(
+                  view.getOwningPropertyName())) {
+                currentAssociation = association;
+                return association;
+              }
+            }
+            if (associationEnd.getOwningPropertyName() != null) {
+              if (associationEnd.getOwningPropertyName().equals(
+                  view.getMappedByName())) {
+                currentAssociation = association;
+                return association;
+              }
+            }
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public void addJPAEdmAssociationView(final JPAEdmAssociationView associationView,
+      final JPAEdmAssociationEndView associationEndView) {
+    if (associationView != null) {
+      currentAssociation = associationView.getEdmAssociation();
+      associationMap
+          .put(currentAssociation.getName(), currentAssociation);
+      associationEndMap.put(currentAssociation.getName(),
+          associationEndView);
+      addJPAEdmRefConstraintView(associationView
+          .getJPAEdmReferentialConstraintView());
+    }
+  }
+
+  @Override
+  public void addJPAEdmRefConstraintView(
+      final JPAEdmReferentialConstraintView refView) {
+    if (refView != null && refView.isExists()) {
+      inconsistentRefConstraintViewList.add(refView);
+    }
+  }
+
+  @Override
+  public JPAEdmReferentialConstraintView getJPAEdmReferentialConstraintView() {
+    if (inconsistentRefConstraintViewList.isEmpty()) {
+      return null;
+    }
+    return inconsistentRefConstraintViewList.get(0);
+  }
+
+  private class JPAEdmAssociationBuilder implements JPAEdmBuilder {
+
+    @Override
+    public void build() throws ODataJPAModelException,
+        ODataJPARuntimeException {
+
+      if (associationEndView != null
+          && searchAssociation(associationEndView) == null) {
+        currentAssociation = new Association();
+        currentAssociation.setEnd1(associationEndView
+            .getEdmAssociationEnd1());
+        currentAssociation.setEnd2(associationEndView
+            .getEdmAssociationEnd2());
+
+        JPAEdmNameBuilder.build(JPAEdmAssociation.this,
+            numberOfSimilarEndPoints);
+
+        associationMap.put(currentAssociation.getName(),
+            currentAssociation);
+
+      } else if (!inconsistentRefConstraintViewList.isEmpty()) {
+        int inconsistentRefConstraintViewSize = inconsistentRefConstraintViewList
+            .size();
+        int index = 0;
+        for (int i = 0; i < inconsistentRefConstraintViewSize; i++) {
+          JPAEdmReferentialConstraintView view = inconsistentRefConstraintViewList
+              .get(index);
+
+          if (view.isExists() && !view.isConsistent()) {
+            view.getBuilder().build();
+          }
+          if (view.isConsistent()) {
+            Association newAssociation = new Association();
+            copyAssociation(newAssociation, associationMap.get(view
+                .getEdmRelationShipName()));
+            newAssociation.setReferentialConstraint(view
+                .getEdmReferentialConstraint());
+            consistentAssociatonList.add(newAssociation);
+            associationMap.put(view.getEdmRelationShipName(),
+                newAssociation);
+            inconsistentRefConstraintViewList.remove(index);
+          } else {
+            associationMap.remove(view.getEdmRelationShipName());
+            index++;
+          }
+        }
+      }
+
+      if (associationMap.size() == consistentAssociatonList.size()) {
+        isConsistent = true;
+      } else {
+        for (String key : associationMap.keySet()) {
+          Association association = associationMap.get(key);
+          if (!consistentAssociatonList.contains(association)) {
+            consistentAssociatonList.add(association);
+          }
+        }
+        isConsistent = true;
+      }
+
+    }
+
+    private void copyAssociation(final Association copyToAssociation,
+        final Association copyFromAssociation) {
+      copyToAssociation.setEnd1(copyFromAssociation.getEnd1());
+      copyToAssociation.setEnd2(copyFromAssociation.getEnd2());
+      copyToAssociation.setName(copyFromAssociation.getName());
+      copyToAssociation.setAnnotationAttributes(copyFromAssociation
+          .getAnnotationAttributes());
+      copyToAssociation.setAnnotationElements(copyFromAssociation
+          .getAnnotationElements());
+      copyToAssociation.setDocumentation(copyFromAssociation
+          .getDocumentation());
+
+    }
+  }
+
+  @Override
+  public int getNumberOfAssociationsWithSimilarEndPoints(
+      final JPAEdmAssociationEndView view) {
+    int count = 0;
+    AssociationEnd currentAssociationEnd1 = view.getEdmAssociationEnd1();
+    AssociationEnd currentAssociationEnd2 = view.getEdmAssociationEnd2();
+    AssociationEnd end1 = null;
+    AssociationEnd end2 = null;
+    for (String key : associationMap.keySet()) {
+      Association association = associationMap.get(key);
+      if (association != null) {
+        end1 = association.getEnd1();
+        end2 = association.getEnd2();
+        if ((end1.getType().equals(currentAssociationEnd1.getType()) && end2
+            .getType().equals(currentAssociationEnd2.getType()))
+            || (end1.getType().equals(
+                currentAssociationEnd2.getType()) && end2
+                .getType().equals(
+                    currentAssociationEnd1.getType()))) {
+          count++;
+        }
+      }
+    }
+    return count;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmAssociationEnd.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmAssociationEnd.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmAssociationEnd.java
new file mode 100644
index 0000000..91176ad
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmAssociationEnd.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *        or more contributor license agreements.  See the NOTICE file
+ *        distributed with this work for additional information
+ *        regarding copyright ownership.  The ASF licenses this file
+ *        to you under the Apache License, Version 2.0 (the
+ *        "License"); you may not use this file except in compliance
+ *        with the License.  You may obtain a copy of the License at
+ * 
+ *          http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *        Unless required by applicable law or agreed to in writing,
+ *        software distributed under the License is distributed on an
+ *        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *        KIND, either express or implied.  See the License for the
+ *        specific language governing permissions and limitations
+ *        under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.processor.core.jpa.model;
+
+import java.lang.reflect.AnnotatedElement;
+
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.metamodel.Attribute.PersistentAttributeType;
+
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.provider.AssociationEnd;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmAssociationEndView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntityTypeView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmPropertyView;
+import org.apache.olingo.odata2.processor.core.jpa.access.model.JPAEdmNameBuilder;
+
+public class JPAEdmAssociationEnd extends JPAEdmBaseViewImpl implements
+    JPAEdmAssociationEndView {
+
+  private JPAEdmEntityTypeView entityTypeView = null;
+  private JPAEdmPropertyView propertyView = null;
+  private AssociationEnd currentAssociationEnd1 = null;
+  private AssociationEnd currentAssociationEnd2 = null;
+  private String columnName;
+  private String referencedColumnName;
+  private String mappedBy;
+  private String ownerPropertyName;
+
+  public JPAEdmAssociationEnd(final JPAEdmEntityTypeView entityTypeView,
+      final JPAEdmPropertyView propertyView) {
+    super(entityTypeView);
+    this.entityTypeView = entityTypeView;
+    this.propertyView = propertyView;
+  }
+
+  @Override
+  public JPAEdmBuilder getBuilder() {
+    if (builder == null) {
+      builder = new JPAEdmAssociationEndBuilder();
+    }
+
+    return builder;
+  }
+
+  @Override
+  public AssociationEnd getEdmAssociationEnd1() {
+    return currentAssociationEnd1;
+  }
+
+  @Override
+  public AssociationEnd getEdmAssociationEnd2() {
+    return currentAssociationEnd2;
+  }
+
+  private class JPAEdmAssociationEndBuilder implements JPAEdmBuilder {
+
+    @Override
+    public void build() throws ODataJPAModelException {
+
+      JoinColumn joinColumn = null;
+
+      currentAssociationEnd1 = new AssociationEnd();
+      currentAssociationEnd2 = new AssociationEnd();
+
+      JPAEdmNameBuilder.build(JPAEdmAssociationEnd.this, entityTypeView,
+          propertyView);
+
+      currentAssociationEnd1.setRole(currentAssociationEnd1.getType()
+          .getName());
+      currentAssociationEnd2.setRole(currentAssociationEnd2.getType()
+          .getName());
+
+      setEdmMultiplicity(propertyView.getJPAAttribute()
+          .getPersistentAttributeType());
+
+      AnnotatedElement annotatedElement = (AnnotatedElement) propertyView.getJPAAttribute()
+          .getJavaMember();
+      if (annotatedElement != null) {
+        joinColumn = annotatedElement.getAnnotation(JoinColumn.class);
+        if (joinColumn != null) {
+          columnName = joinColumn.name();
+          referencedColumnName = joinColumn.referencedColumnName();
+        }
+
+      }
+      ownerPropertyName = propertyView.getJPAAttribute().getName();
+
+    }
+
+    private void setEdmMultiplicity(final PersistentAttributeType type) {
+      AnnotatedElement annotatedElement = (AnnotatedElement) propertyView.getJPAAttribute()
+          .getJavaMember();
+      switch (type) {
+      case ONE_TO_MANY:
+        currentAssociationEnd1.setMultiplicity(EdmMultiplicity.ONE);
+        currentAssociationEnd2.setMultiplicity(EdmMultiplicity.MANY);
+        if (annotatedElement != null) {
+          OneToMany reln = annotatedElement.getAnnotation(OneToMany.class);
+          if (reln != null) {
+            mappedBy = reln.mappedBy();
+          }
+        }
+        break;
+      case MANY_TO_MANY:
+        currentAssociationEnd1.setMultiplicity(EdmMultiplicity.MANY);
+        currentAssociationEnd2.setMultiplicity(EdmMultiplicity.MANY);
+        if (annotatedElement != null) {
+          ManyToMany reln = annotatedElement.getAnnotation(ManyToMany.class);
+          if (reln != null) {
+            mappedBy = reln.mappedBy();
+          }
+        }
+        break;
+      case MANY_TO_ONE:
+        currentAssociationEnd1.setMultiplicity(EdmMultiplicity.MANY);
+        currentAssociationEnd2.setMultiplicity(EdmMultiplicity.ONE);
+        break;
+      case ONE_TO_ONE:
+        currentAssociationEnd1.setMultiplicity(EdmMultiplicity.ONE);
+        currentAssociationEnd2.setMultiplicity(EdmMultiplicity.ONE);
+        if (annotatedElement != null) {
+          OneToOne reln = annotatedElement.getAnnotation(OneToOne.class);
+          if (reln != null) {
+            mappedBy = reln.mappedBy();
+          }
+        }
+        break;
+      default:
+        break;
+      }
+    }
+  }
+
+  @Override
+  public boolean compare(final AssociationEnd end1, final AssociationEnd end2) {
+    if ((end1.getType().equals(currentAssociationEnd1.getType())
+        && end2.getType().equals(currentAssociationEnd2.getType())
+        && end1.getMultiplicity().equals(
+            currentAssociationEnd1.getMultiplicity()) && end2
+        .getMultiplicity().equals(
+            currentAssociationEnd2.getMultiplicity()))
+        || (end1.getType().equals(currentAssociationEnd2.getType())
+            && end2.getType().equals(
+                currentAssociationEnd1.getType())
+            && end1.getMultiplicity().equals(
+                currentAssociationEnd2.getMultiplicity()) && end2
+            .getMultiplicity().equals(
+                currentAssociationEnd1.getMultiplicity()))) {
+      return true;
+    }
+
+    return false;
+  }
+
+  @Override
+  public String getJoinColumnName() {
+    return columnName;
+  }
+
+  @Override
+  public String getJoinColumnReferenceColumnName() {
+    return referencedColumnName;
+  }
+
+  @Override
+  public String getMappedByName() {
+    return mappedBy;
+  }
+
+  @Override
+  public String getOwningPropertyName() {
+    return ownerPropertyName;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmAssociationSet.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmAssociationSet.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmAssociationSet.java
new file mode 100644
index 0000000..d6ce8ac
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/model/JPAEdmAssociationSet.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *        or more contributor license agreements.  See the NOTICE file
+ *        distributed with this work for additional information
+ *        regarding copyright ownership.  The ASF licenses this file
+ *        to you under the Apache License, Version 2.0 (the
+ *        "License"); you may not use this file except in compliance
+ *        with the License.  You may obtain a copy of the License at
+ * 
+ *          http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *        Unless required by applicable law or agreed to in writing,
+ *        software distributed under the License is distributed on an
+ *        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *        KIND, either express or implied.  See the License for the
+ *        specific language governing permissions and limitations
+ *        under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.processor.core.jpa.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.Association;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSet;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSetEnd;
+import org.apache.olingo.odata2.api.edm.provider.EntitySet;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmBuilder;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmAssociationSetView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmAssociationView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntitySetView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmSchemaView;
+import org.apache.olingo.odata2.processor.core.jpa.access.model.JPAEdmNameBuilder;
+
+public class JPAEdmAssociationSet extends JPAEdmBaseViewImpl implements
+    JPAEdmAssociationSetView {
+
+  private JPAEdmSchemaView schemaView;
+  private AssociationSet currentAssociationSet;
+  private List<AssociationSet> associationSetList;
+  private Association currentAssociation;
+
+  public JPAEdmAssociationSet(final JPAEdmSchemaView view) {
+    super(view);
+    schemaView = view;
+  }
+
+  @Override
+  public JPAEdmBuilder getBuilder() {
+    if (builder == null) {
+      builder = new JPAEdmAssociationSetBuilder();
+    }
+
+    return builder;
+  }
+
+  @Override
+  public List<AssociationSet> getConsistentEdmAssociationSetList() {
+    return associationSetList;
+  }
+
+  @Override
+  public AssociationSet getEdmAssociationSet() {
+    return currentAssociationSet;
+  }
+
+  @Override
+  public Association getEdmAssociation() {
+    return currentAssociation;
+  }
+
+  private class JPAEdmAssociationSetBuilder implements JPAEdmBuilder {
+
+    @Override
+    public void build() throws ODataJPAModelException {
+
+      if (associationSetList == null) {
+        associationSetList = new ArrayList<AssociationSet>();
+      }
+
+      JPAEdmAssociationView associationView = schemaView
+          .getJPAEdmAssociationView();
+      JPAEdmEntitySetView entitySetView = schemaView
+          .getJPAEdmEntityContainerView().getJPAEdmEntitySetView();
+
+      List<EntitySet> entitySetList = entitySetView
+          .getConsistentEdmEntitySetList();
+      if (associationView.isConsistent()) {
+        for (Association association : associationView
+            .getConsistentEdmAssociationList()) {
+
+          currentAssociation = association;
+
+          FullQualifiedName fQname = new FullQualifiedName(schemaView
+              .getEdmSchema().getNamespace(),
+              association.getName());
+          currentAssociationSet = new AssociationSet();
+          currentAssociationSet.setAssociation(fQname);
+
+          int endCount = 0;
+          short endFlag = 0;
+          for (EntitySet entitySet : entitySetList) {
+            fQname = entitySet.getEntityType();
+            endFlag = 0;
+            if (fQname.equals(association.getEnd1().getType())
+                || ++endFlag > 1
+                || fQname.equals(association.getEnd2()
+                    .getType())) {
+
+              AssociationSetEnd end = new AssociationSetEnd();
+              end.setEntitySet(entitySet.getName());
+              if (endFlag == 0) {
+                currentAssociationSet.setEnd1(end);
+                end.setRole(association.getEnd1().getRole());
+                endCount++;
+              } else {
+                endCount++;
+                currentAssociationSet.setEnd2(end);
+                end.setRole(association.getEnd2().getRole());
+              }
+
+              if (endCount == 2) {
+                break;
+              }
+            }
+          }
+          if (endCount == 2) {
+            JPAEdmNameBuilder.build(JPAEdmAssociationSet.this);
+            associationSetList.add(currentAssociationSet);
+          }
+
+        }
+
+      }
+    }
+  }
+}