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);
+ }
+
+ }
+
+ }
+ }
+ }
+}