You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2015/07/12 15:53:24 UTC
olingo-odata2 git commit: [OLINGO-720] - Provide capability to extend
JPA Query object
Repository: olingo-odata2
Updated Branches:
refs/heads/master 9a7e91357 -> cb29fa48d
[OLINGO-720] - Provide capability to extend JPA Query object
Signed-off-by: Chandan V A <ch...@sap.com>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/cb29fa48
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/cb29fa48
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/cb29fa48
Branch: refs/heads/master
Commit: cb29fa48da7d712083cda21e0cd6e543389e64ba
Parents: 9a7e913
Author: Chandan V A <ch...@sap.com>
Authored: Sun Jul 12 19:23:05 2015 +0530
Committer: Chandan V A <ch...@sap.com>
Committed: Sun Jul 12 19:23:05 2015 +0530
----------------------------------------------------------------------
.../ODataJPAQueryExtensionEntityListener.java | 116 +++++++++
.../api/ODataJPATombstoneEntityListener.java | 7 +
.../jpa/processor/api/jpql/JPQLContext.java | 4 +-
.../core/access/data/JPAProcessorImpl.java | 256 +++++-------------
.../core/access/data/JPAQueryBuilder.java | 259 +++++++++++++++++++
.../core/ODataJPAProcessorDefaultTest.java | 43 +--
.../core/access/data/JPAProcessorImplTest.java | 2 +
.../core/access/data/JPAQueryBuilderTest.java | 254 ++++++++++++++++++
.../processor/core/mock/ODataContextMock.java | 7 +
.../core/mock/ODataJPAContextMock.java | 1 +
.../jpa/processor/ref/model/Customer.java | 2 +
.../ref/web/JPAReferenceServiceFactory.java | 1 +
12 files changed, 744 insertions(+), 208 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb29fa48/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAQueryExtensionEntityListener.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAQueryExtensionEntityListener.java b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAQueryExtensionEntityListener.java
new file mode 100644
index 0000000..0ad3ac4
--- /dev/null
+++ b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAQueryExtensionEntityListener.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.jpa.processor.api;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+
+/**
+ * Extend this class to build JPA Query object for a given OData request. The extended class can be registered as JPA
+ * entity listeners.The implemented JPA Entity Listener classes will be called back from OData JPA Processor Library.
+ */
+public abstract class ODataJPAQueryExtensionEntityListener extends ODataJPATombstoneEntityListener {
+ /**
+ * Override this method to build JPA Query for OData request - GetEntitySet; SELECT *
+ * @param uriInfo is a reference to OData request
+ * @param em is a reference to {@link javax.persistence.EntityManager}
+ * @return an instance of type {@link javax.persistence.Query}
+ */
+ public Query getQuery(GetEntitySetUriInfo uriInfo, EntityManager em) {
+ return null;
+ }
+
+ /**
+ * Override this method to build JPA Query for OData request - GetEntity; SELECT SINGLE with key in WHERE
+ * clause
+ * @param uriInfo is a reference to OData request
+ * @param em is a reference to {@link javax.persistence.EntityManager}
+ * @return an instance of type {@link javax.persistence.Query}
+ */
+ public Query getQuery(GetEntityUriInfo uriInfo, EntityManager em) {
+ return null;
+ }
+
+ /**
+ * Override this method to build JPA Query for OData request - GetEntity Count; SELECT SINGLE with key in WHERE
+ * clause
+ * @param uriInfo is a reference to OData request
+ * @param em is a reference to {@link javax.persistence.EntityManager}
+ * @return an instance of type {@link javax.persistence.Query}
+ */
+ public Query getQuery(GetEntityCountUriInfo uriInfo, EntityManager em) {
+ return null;
+ }
+
+ /**
+ * Override this method to build JPA Query for OData request - GetEntitySet Count; SELECT COUNT(*)
+ * @param uriInfo is a reference to OData request
+ * @param em is a reference to {@link javax.persistence.EntityManager}
+ * @return an instance of type {@link javax.persistence.Query}
+ */
+ public Query getQuery(GetEntitySetCountUriInfo uriInfo, EntityManager em) {
+ return null;
+ }
+
+ /**
+ * Override this method to build JPA Query for OData request - Update; SELECT SINGLE with key in WHERE
+ * clause
+ * @param uriInfo is a reference to OData request
+ * @param em is a reference to {@link javax.persistence.EntityManager}
+ * @return an instance of type {@link javax.persistence.Query}
+ */
+ public Query getQuery(PutMergePatchUriInfo uriInfo, EntityManager em) {
+ return null;
+ }
+
+ /**
+ * Override this method to build JPA Query for OData request - Delete; SELECT SINGLE with key in WHERE
+ * clause
+ * @param uriInfo is a reference to OData request
+ * @param em is a reference to {@link javax.persistence.EntityManager}
+ * @return an instance of type {@link javax.persistence.Query}
+ */
+ public Query getQuery(DeleteUriInfo uriInfo, EntityManager em) {
+ return null;
+ }
+
+ @Override
+ public String generateDeltaToken(List<Object> deltas, Query query) {
+ return null;
+ }
+
+ /**
+ * Implement this method to indicate whether the extended class can handle OData Tombstone feature as well
+ * @return false by default
+ */
+ @Override
+ public boolean isTombstoneSupported() {
+ return false;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb29fa48/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPATombstoneEntityListener.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPATombstoneEntityListener.java b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPATombstoneEntityListener.java
index 148fa38..ff85653 100644
--- a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPATombstoneEntityListener.java
+++ b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPATombstoneEntityListener.java
@@ -57,4 +57,11 @@ public abstract class ODataJPATombstoneEntityListener {
*/
public abstract String generateDeltaToken(List<Object> deltas, Query query);
+ /**
+ * Implement this method to indicate whether the extended class can handle OData Tombstone feature as well
+ * @return true by default
+ */
+ public boolean isTombstoneSupported() {
+ return true;
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb29fa48/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/jpql/JPQLContext.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/jpql/JPQLContext.java b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/jpql/JPQLContext.java
index a6230ad..672f808 100644
--- a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/jpql/JPQLContext.java
+++ b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/jpql/JPQLContext.java
@@ -159,6 +159,8 @@ public abstract class JPQLContext implements JPQLContextView {
*
*/
public static abstract class JPQLContextBuilder {
+ private static final String ALIAS = "E";
+
/**
* alias counter is an integer counter that is incremented by "1" for
* every new alias name generation. The value of counter is used in the
@@ -228,7 +230,7 @@ public abstract class JPQLContext implements JPQLContextView {
* @return a String representing JPA entity alias name
*/
protected String generateJPAEntityAlias() {
- return new String("E" + ++aliasCounter);
+ return new String(ALIAS + ++aliasCounter);
}
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb29fa48/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImpl.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImpl.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImpl.java
index da5a1e1..ad8810c 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImpl.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImpl.java
@@ -35,6 +35,7 @@ import org.apache.olingo.odata2.api.edm.EdmException;
import org.apache.olingo.odata2.api.edm.EdmMapping;
import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
import org.apache.olingo.odata2.api.uri.UriInfo;
import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
import org.apache.olingo.odata2.api.uri.info.GetEntityCountUriInfo;
@@ -55,15 +56,15 @@ import org.apache.olingo.odata2.jpa.processor.api.access.JPAMethodContext;
import org.apache.olingo.odata2.jpa.processor.api.access.JPAProcessor;
import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
-import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContext;
import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContextType;
-import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement;
import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping;
import org.apache.olingo.odata2.jpa.processor.core.ODataEntityParser;
import org.apache.olingo.odata2.jpa.processor.core.access.data.JPAPage.JPAPageBuilder;
+import org.apache.olingo.odata2.jpa.processor.core.access.data.JPAQueryBuilder.JPAQueryInfo;
public class JPAProcessorImpl implements JPAProcessor {
+ private static final String DELTATOKEN = "!deltatoken";
ODataJPAContext oDataJPAContext;
EntityManager em;
@@ -128,78 +129,52 @@ public class JPAProcessorImpl implements JPAProcessor {
public List<Object> process(final GetEntitySetUriInfo uriParserResultView)
throws ODataJPAModelException, ODataJPARuntimeException {
+ List<Object> result = null;
if (uriParserResultView.getFunctionImport() != null) {
return (List<Object>) process((GetFunctionImportUriInfo) uriParserResultView);
}
+
InlineCount inlineCount = uriParserResultView.getInlineCount();
Integer top = uriParserResultView.getTop() == null ? 1 : uriParserResultView.getTop().intValue();
boolean hasNoAllPages = inlineCount == null ? true : !inlineCount.equals(InlineCount.ALLPAGES);
if (top.intValue() == 0 && hasNoAllPages) {
return new ArrayList<Object>();
}
- JPQLContextType contextType = null;
- try {
- if (uriParserResultView.getNavigationSegments().size() > 0) {
- contextType = JPQLContextType.JOIN;
- } else {
- contextType = JPQLContextType.SELECT;
- }
-
- JPQLContext jpqlContext = null;
-
- if (oDataJPAContext.getPageSize() > 0) {
- jpqlContext = JPQLContext.createBuilder(contextType,
- uriParserResultView, true).build();
- } else {
- jpqlContext = JPQLContext.createBuilder(contextType,
- uriParserResultView).build();
- }
- JPQLStatement jpqlStatement = JPQLStatement.createBuilder(jpqlContext)
- .build();
+ try {
+ JPAEdmMapping mapping = (JPAEdmMapping) uriParserResultView.getTargetEntitySet().getEntityType().getMapping();
+ JPAQueryBuilder queryBuilder = new JPAQueryBuilder(oDataJPAContext);
+ JPAQueryInfo queryInfo = queryBuilder.build(uriParserResultView);
+ Query query = queryInfo.getQuery();
+ ODataJPATombstoneEntityListener listener =
+ queryBuilder.getODataJPATombstoneEntityListener((UriInfo) uriParserResultView);
Map<String, String> customQueryOptions = uriParserResultView.getCustomQueryOptions();
String deltaToken = null;
if (customQueryOptions != null) {
- deltaToken = uriParserResultView.getCustomQueryOptions().get("!deltatoken");
+ deltaToken = uriParserResultView.getCustomQueryOptions().get(DELTATOKEN);
}
if (deltaToken != null) {
ODataJPATombstoneContext.setDeltaToken(deltaToken);
}
-
- Query query = null;
- List<Object> result = null;
-
- JPAEdmMapping mapping = (JPAEdmMapping) uriParserResultView.getTargetEntitySet().getEntityType().getMapping();
- ODataJPATombstoneEntityListener listener = null;
- if (mapping.getODataJPATombstoneEntityListener() != null) {
- listener = (ODataJPATombstoneEntityListener) mapping.getODataJPATombstoneEntityListener().newInstance();
- query = listener.getQuery(uriParserResultView, em);
- }
- if (query == null) {
- query = em.createQuery(jpqlStatement.toString());
- if (listener != null) {
- query.getResultList();
- List<Object> deltaResult =
- (List<Object>) ODataJPATombstoneContext.getDeltaResult(((EdmMapping) mapping).getInternalName());
- result = handlePaging(deltaResult, uriParserResultView);
- } else {
- result = handlePaging(query, uriParserResultView);
- }
+ if (listener != null && (!queryInfo.isTombstoneQuery() && listener.isTombstoneSupported())) {
+ query.getResultList();
+ List<Object> deltaResult =
+ (List<Object>) ODataJPATombstoneContext.getDeltaResult(((EdmMapping) mapping).getInternalName());
+ result = handlePaging(deltaResult, uriParserResultView);
+ ODataJPATombstoneContext.setDeltaToken(listener.generateDeltaToken((List<Object>) result, query));
} else {
result = handlePaging(query, uriParserResultView);
}
-
- // Set New Token
- if (listener != null) {
- ODataJPATombstoneContext.setDeltaToken(listener.generateDeltaToken((List<Object>) result, query));
- }
-
return result == null ? new ArrayList<Object>() : result;
-
- } catch (Exception e) {
+ } catch (EdmException e) {
+ throw ODataJPARuntimeException.throwException(
+ ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
+ } catch (InstantiationException e) {
+ throw ODataJPARuntimeException.throwException(
+ ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
+ } catch (IllegalAccessException e) {
throw ODataJPARuntimeException.throwException(
ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
-
}
}
@@ -207,18 +182,7 @@ public class JPAProcessorImpl implements JPAProcessor {
@Override
public <T> Object process(GetEntityUriInfo uriParserResultView)
throws ODataJPAModelException, ODataJPARuntimeException {
-
- JPQLContextType contextType = null;
- if (uriParserResultView instanceof GetEntityUriInfo) {
- uriParserResultView = ((GetEntityUriInfo) uriParserResultView);
- if (uriParserResultView.getNavigationSegments().size() > 0) {
- contextType = JPQLContextType.JOIN_SINGLE;
- } else {
- contextType = JPQLContextType.SELECT_SINGLE;
- }
- }
-
- return readEntity(uriParserResultView, contextType);
+ return readEntity(new JPAQueryBuilder(oDataJPAContext).build(uriParserResultView));
}
/* Process $count for Get Entity Set Request */
@@ -226,36 +190,13 @@ public class JPAProcessorImpl implements JPAProcessor {
public long process(final GetEntitySetCountUriInfo resultsView)
throws ODataJPAModelException, ODataJPARuntimeException {
- JPQLContextType contextType = null;
- try {
- if (!resultsView.getStartEntitySet().getName()
- .equals(resultsView.getTargetEntitySet().getName())) {
- contextType = JPQLContextType.JOIN_COUNT;
- } else {
- contextType = JPQLContextType.SELECT_COUNT;
- }
- } catch (EdmException e) {
- ODataJPARuntimeException.throwException(
- ODataJPARuntimeException.GENERAL, e);
+ JPAQueryBuilder queryBuilder = new JPAQueryBuilder(oDataJPAContext);
+ Query query = queryBuilder.build(resultsView);
+ List<?> resultList = query.getResultList();
+ if (resultList != null && resultList.size() == 1) {
+ return Long.valueOf(resultList.get(0).toString());
}
- JPQLContext jpqlContext = JPQLContext.createBuilder(contextType,
- resultsView).build();
-
- JPQLStatement jpqlStatement = JPQLStatement.createBuilder(jpqlContext)
- .build();
- Query query = null;
- try {
-
- query = em.createQuery(jpqlStatement.toString());
- List<?> resultList = query.getResultList();
- if (resultList != null && resultList.size() == 1) {
- return Long.valueOf(resultList.get(0).toString());
- }
- } catch (IllegalArgumentException e) {
- throw ODataJPARuntimeException.throwException(
- ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
- }
return 0;
}
@@ -263,37 +204,12 @@ public class JPAProcessorImpl implements JPAProcessor {
@Override
public long process(final GetEntityCountUriInfo resultsView) throws ODataJPAModelException, ODataJPARuntimeException {
- JPQLContextType contextType = null;
- try {
- if (!resultsView.getStartEntitySet().getName()
- .equals(resultsView.getTargetEntitySet().getName())) {
- contextType = JPQLContextType.JOIN_COUNT;
- } else {
- contextType = JPQLContextType.SELECT_COUNT;
- }
- } catch (EdmException e) {
- ODataJPARuntimeException.throwException(
- ODataJPARuntimeException.GENERAL, e);
- }
-
- JPQLContext jpqlContext = JPQLContext.createBuilder(contextType,
- resultsView).build();
-
- JPQLStatement jpqlStatement = JPQLStatement.createBuilder(jpqlContext)
- .build();
- Query query = null;
- try {
-
- query = em.createQuery(jpqlStatement.toString());
- List<?> resultList = query.getResultList();
- if (resultList != null && resultList.size() == 1) {
- return Long.valueOf(resultList.get(0).toString());
- }
- } catch (IllegalArgumentException e) {
- throw ODataJPARuntimeException.throwException(
- ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
+ JPAQueryBuilder queryBuilder = new JPAQueryBuilder(oDataJPAContext);
+ Query query = queryBuilder.build(resultsView);
+ List<?> resultList = query.getResultList();
+ if (resultList != null && resultList.size() == 1) {
+ return Long.valueOf(resultList.get(0).toString());
}
-
return 0;
}
@@ -329,38 +245,19 @@ public class JPAProcessorImpl implements JPAProcessor {
@Override
public Object process(DeleteUriInfo uriParserResultView, final String contentType)
throws ODataJPAModelException, ODataJPARuntimeException {
- JPQLContextType contextType = null;
- try {
- if (uriParserResultView instanceof DeleteUriInfo) {
- if (((UriInfo) uriParserResultView).isLinks()) {
- return deleteLink(uriParserResultView);
- }
- uriParserResultView = ((DeleteUriInfo) uriParserResultView);
- if (!((DeleteUriInfo) uriParserResultView).getStartEntitySet().getName()
- .equals(((DeleteUriInfo) uriParserResultView).getTargetEntitySet().getName())) {
- contextType = JPQLContextType.JOIN_SINGLE;
- } else {
- contextType = JPQLContextType.SELECT_SINGLE;
- }
+ if (uriParserResultView instanceof DeleteUriInfo) {
+ if (((UriInfo) uriParserResultView).isLinks()) {
+ return deleteLink(uriParserResultView);
}
- } catch (EdmException e) {
- ODataJPARuntimeException.throwException(
- ODataJPARuntimeException.GENERAL, e);
}
-
- Object selectedObject = readEntity(uriParserResultView, contextType);
+ Object selectedObject = readEntity(new JPAQueryBuilder(oDataJPAContext).build(uriParserResultView));
if (selectedObject != null) {
- try {
- boolean isLocalTransaction = setTransaction();
- em.remove(selectedObject);
- em.flush();
- if (isLocalTransaction) {
- oDataJPAContext.getODataJPATransaction().commit();
- }
- } catch (Exception e) {
- throw ODataJPARuntimeException.throwException(
- ODataJPARuntimeException.ERROR_JPQL_DELETE_REQUEST, e);
+ boolean isLocalTransaction = setTransaction();
+ em.remove(selectedObject);
+ em.flush();
+ if (isLocalTransaction) {
+ oDataJPAContext.getODataJPATransaction().commit();
}
}
return selectedObject;
@@ -402,31 +299,12 @@ public class JPAProcessorImpl implements JPAProcessor {
}
/* Common method for Read and Delete */
- private Object readEntity(final Object uriParserResultView, final JPQLContextType contextType)
- throws ODataJPAModelException, ODataJPARuntimeException {
-
+ private Object readEntity(final Query query) throws ODataJPARuntimeException {
Object selectedObject = null;
-
- if (uriParserResultView instanceof DeleteUriInfo || uriParserResultView instanceof GetEntityUriInfo
- || uriParserResultView instanceof PutMergePatchUriInfo) {
-
- JPQLContext selectJPQLContext = JPQLContext.createBuilder(
- contextType, uriParserResultView).build();
-
- JPQLStatement selectJPQLStatement = JPQLStatement.createBuilder(
- selectJPQLContext).build();
- Query query = null;
- try {
- query = em.createQuery(selectJPQLStatement.toString());
- @SuppressWarnings("rawtypes")
- final List resultList = query.getResultList();
- if (!resultList.isEmpty()) {
- selectedObject = resultList.get(0);
- }
- } catch (IllegalArgumentException e) {
- throw ODataJPARuntimeException.throwException(
- ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
- }
+ @SuppressWarnings("rawtypes")
+ final List resultList = query.getResultList();
+ if (!resultList.isEmpty()) {
+ selectedObject = resultList.get(0);
}
return selectedObject;
}
@@ -462,9 +340,12 @@ public class JPAProcessorImpl implements JPAProcessor {
}
return jpaEntity;
}
- } catch (Exception e) {
+ } catch (ODataBadRequestException e) {
+ throw ODataJPARuntimeException.throwException(
+ ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
+ } catch (EdmException e) {
throw ODataJPARuntimeException.throwException(
- ODataJPARuntimeException.ERROR_JPQL_CREATE_REQUEST, e);
+ ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
}
return null;
}
@@ -472,21 +353,10 @@ public class JPAProcessorImpl implements JPAProcessor {
private <T> Object processUpdate(PutMergePatchUriInfo updateView,
final InputStream content, final Map<String, Object> properties, final String requestContentType)
throws ODataJPAModelException, ODataJPARuntimeException {
- JPQLContextType contextType = null;
Object jpaEntity = null;
try {
boolean isLocalTransaction = setTransaction();
- if (updateView instanceof PutMergePatchUriInfo) {
- updateView = ((PutMergePatchUriInfo) updateView);
- if (!((PutMergePatchUriInfo) updateView).getStartEntitySet().getName()
- .equals(((PutMergePatchUriInfo) updateView).getTargetEntitySet().getName())) {
- contextType = JPQLContextType.JOIN_SINGLE;
- } else {
- contextType = JPQLContextType.SELECT_SINGLE;
- }
- }
-
- jpaEntity = readEntity(updateView, contextType);
+ jpaEntity = readEntity(new JPAQueryBuilder(oDataJPAContext).build(updateView));
if (jpaEntity == null) {
throw ODataJPARuntimeException
@@ -497,10 +367,10 @@ public class JPAProcessorImpl implements JPAProcessor {
final EdmEntityType oDataEntityType = oDataEntitySet.getEntityType();
final JPAEntity virtualJPAEntity = new JPAEntity(oDataEntityType, oDataEntitySet, oDataJPAContext);
virtualJPAEntity.setJPAEntity(jpaEntity);
-
if (content != null) {
final ODataEntityParser oDataEntityParser = new ODataEntityParser(oDataJPAContext);
- final ODataEntry oDataEntry = oDataEntityParser.parseEntry(oDataEntitySet, content, requestContentType, false);
+ ODataEntry oDataEntry;
+ oDataEntry = oDataEntityParser.parseEntry(oDataEntitySet, content, requestContentType, false);
virtualJPAEntity.update(oDataEntry);
} else if (properties != null) {
virtualJPAEntity.update(properties);
@@ -511,11 +381,13 @@ public class JPAProcessorImpl implements JPAProcessor {
if (isLocalTransaction) {
oDataJPAContext.getODataJPATransaction().commit();
}
- } catch (Exception e) {
+ } catch (ODataBadRequestException e) {
throw ODataJPARuntimeException.throwException(
- ODataJPARuntimeException.ERROR_JPQL_UPDATE_REQUEST, e);
+ ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
+ } catch (EdmException e) {
+ throw ODataJPARuntimeException.throwException(
+ ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
}
-
return jpaEntity;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb29fa48/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java
new file mode 100644
index 0000000..c5e61a8
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilder.java
@@ -0,0 +1,259 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.jpa.processor.core.access.data;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.uri.UriInfo;
+import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPAQueryExtensionEntityListener;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPATombstoneEntityListener;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContext;
+import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContextType;
+import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping;
+
+public class JPAQueryBuilder {
+
+ public enum UriInfoType {
+ GetEntitySet,
+ GetEntity,
+ GetEntitySetCount,
+ GetEntityCount,
+ PutMergePatch,
+ Delete
+ };
+
+ private EntityManager em = null;
+ private int pageSize = 0;
+
+ public JPAQueryBuilder(ODataJPAContext odataJPAContext) {
+ this.em = odataJPAContext.getEntityManager();
+ this.pageSize = odataJPAContext.getPageSize();
+ }
+
+ public JPAQueryInfo build(GetEntitySetUriInfo uriInfo) throws ODataJPARuntimeException {
+ JPAQueryInfo queryInfo = new JPAQueryInfo();
+ Query query = null;
+ try {
+ ODataJPATombstoneEntityListener listener = getODataJPATombstoneEntityListener((UriInfo) uriInfo);
+ if (listener != null) {
+ query = listener.getQuery(uriInfo, em);
+ }
+ if (query == null) {
+ query = buildQuery((UriInfo) uriInfo, UriInfoType.GetEntitySet);
+ } else {
+ queryInfo.setTombstoneQuery(true);
+ }
+ } catch (Exception e) {
+ throw ODataJPARuntimeException.throwException(
+ ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
+ }
+ queryInfo.setQuery(query);
+ return queryInfo;
+ }
+
+ public Query build(GetEntityUriInfo uriInfo) throws ODataJPARuntimeException {
+ Query query = null;
+ try {
+ ODataJPAQueryExtensionEntityListener listener = getODataJPAQuertEntityListener((UriInfo) uriInfo);
+ if (listener != null) {
+ query = listener.getQuery(uriInfo, em);
+ }
+ if (query == null) {
+ query = buildQuery((UriInfo) uriInfo, UriInfoType.GetEntity);
+ }
+ } catch (Exception e) {
+ throw ODataJPARuntimeException.throwException(
+ ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
+ }
+ return query;
+ }
+
+ public Query build(GetEntitySetCountUriInfo uriInfo) throws ODataJPARuntimeException {
+ Query query = null;
+ try {
+ ODataJPAQueryExtensionEntityListener listener = getODataJPAQuertEntityListener((UriInfo) uriInfo);
+ if (listener != null) {
+ query = listener.getQuery(uriInfo, em);
+ }
+ if (query == null) {
+ query = buildQuery((UriInfo) uriInfo, UriInfoType.GetEntitySetCount);
+ }
+ } catch (Exception e) {
+ throw ODataJPARuntimeException.throwException(
+ ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
+ }
+ return query;
+ }
+
+ public Query build(GetEntityCountUriInfo uriInfo) throws ODataJPARuntimeException {
+ Query query = null;
+ try {
+ ODataJPAQueryExtensionEntityListener listener = getODataJPAQuertEntityListener((UriInfo) uriInfo);
+ if (listener != null) {
+ query = listener.getQuery(uriInfo, em);
+ }
+ if (query == null) {
+ query = buildQuery((UriInfo) uriInfo, UriInfoType.GetEntityCount);
+ }
+ } catch (Exception e) {
+ throw ODataJPARuntimeException.throwException(
+ ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
+ }
+ return query;
+ }
+
+ public Query build(DeleteUriInfo uriInfo) throws ODataJPARuntimeException {
+ Query query = null;
+ try {
+ ODataJPAQueryExtensionEntityListener listener = getODataJPAQuertEntityListener((UriInfo) uriInfo);
+ if (listener != null) {
+ query = listener.getQuery(uriInfo, em);
+ }
+ if (query == null) {
+ query = buildQuery((UriInfo) uriInfo, UriInfoType.Delete);
+ }
+ } catch (Exception e) {
+ throw ODataJPARuntimeException.throwException(
+ ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
+ }
+ return query;
+ }
+
+ public Query build(PutMergePatchUriInfo uriInfo) throws ODataJPARuntimeException {
+ Query query = null;
+ try {
+ ODataJPAQueryExtensionEntityListener listener = getODataJPAQuertEntityListener((UriInfo) uriInfo);
+ if (listener != null) {
+ query = listener.getQuery(uriInfo, em);
+ }
+ if (query == null) {
+ query = buildQuery((UriInfo) uriInfo, UriInfoType.PutMergePatch);
+ }
+ } catch (Exception e) {
+ throw ODataJPARuntimeException.throwException(
+ ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
+ }
+ return query;
+ }
+
+ private Query buildQuery(UriInfo uriParserResultView, UriInfoType type)
+ throws EdmException,
+ ODataJPAModelException, ODataJPARuntimeException {
+
+ Query query = null;
+ JPQLContextType contextType = determineJPQLContextType(uriParserResultView, type);
+ JPQLContext jpqlContext = buildJPQLContext(contextType, uriParserResultView);
+ JPQLStatement jpqlStatement = JPQLStatement.createBuilder(jpqlContext)
+ .build();
+ query = em.createQuery(jpqlStatement.toString());
+
+ return query;
+ }
+
+ public ODataJPAQueryExtensionEntityListener getODataJPAQuertEntityListener(UriInfo uriInfo) throws EdmException,
+ InstantiationException, IllegalAccessException {
+ ODataJPAQueryExtensionEntityListener queryListener = null;
+ ODataJPATombstoneEntityListener listener = getODataJPATombstoneEntityListener(uriInfo);
+ if (listener instanceof ODataJPAQueryExtensionEntityListener) {
+ queryListener = (ODataJPAQueryExtensionEntityListener) listener;
+ }
+ return queryListener;
+ }
+
+ public ODataJPATombstoneEntityListener getODataJPATombstoneEntityListener(UriInfo uriParserResultView)
+ throws InstantiationException, IllegalAccessException, EdmException {
+ JPAEdmMapping mapping = (JPAEdmMapping) uriParserResultView.getTargetEntitySet().getEntityType().getMapping();
+ ODataJPATombstoneEntityListener listener = null;
+ if (mapping.getODataJPATombstoneEntityListener() != null) {
+ listener = (ODataJPATombstoneEntityListener) mapping.getODataJPATombstoneEntityListener().newInstance();
+ }
+ return listener;
+ }
+
+ public JPQLContext buildJPQLContext(JPQLContextType contextType, UriInfo uriParserResultView)
+ throws ODataJPAModelException, ODataJPARuntimeException {
+ JPQLContext jpqlContext = null;
+ if (pageSize > 0 && (contextType == JPQLContextType.SELECT || contextType == JPQLContextType.JOIN)) {
+ jpqlContext = JPQLContext.createBuilder(contextType,
+ uriParserResultView, true).build();
+ } else {
+ jpqlContext = JPQLContext.createBuilder(contextType,
+ uriParserResultView).build();
+ }
+ return jpqlContext;
+ }
+
+ public JPQLContextType determineJPQLContextType(UriInfo uriParserResultView, UriInfoType type) {
+ JPQLContextType contextType = null;
+
+ if (uriParserResultView.getNavigationSegments().size() > 0) {
+ if (type == UriInfoType.GetEntitySet) {
+ contextType = JPQLContextType.JOIN;
+ } else if (type == UriInfoType.Delete || type == UriInfoType.Delete || type == UriInfoType.GetEntity
+ || type == UriInfoType.PutMergePatch) {
+ contextType = JPQLContextType.JOIN_SINGLE;
+ } else if (type == UriInfoType.GetEntitySetCount || type == UriInfoType.GetEntityCount) {
+ contextType = JPQLContextType.JOIN_COUNT;
+ }
+ } else {
+ if (type == UriInfoType.GetEntitySet) {
+ contextType = JPQLContextType.SELECT;
+ } else if (type == UriInfoType.Delete || type == UriInfoType.GetEntity
+ || type == UriInfoType.PutMergePatch) {
+ contextType = JPQLContextType.SELECT_SINGLE;
+ } else if (type == UriInfoType.GetEntitySetCount || type == UriInfoType.GetEntityCount) {
+ contextType = JPQLContextType.SELECT_COUNT;
+ }
+ }
+ return contextType;
+ }
+
+ public final class JPAQueryInfo {
+ private Query query = null;
+ private boolean isTombstoneQuery = false;
+
+ public Query getQuery() {
+ return query;
+ }
+
+ public void setQuery(Query query) {
+ this.query = query;
+ }
+
+ public boolean isTombstoneQuery() {
+ return isTombstoneQuery;
+ }
+
+ public void setTombstoneQuery(boolean isTombstoneQuery) {
+ this.isTombstoneQuery = isTombstoneQuery;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb29fa48/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAProcessorDefaultTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAProcessorDefaultTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAProcessorDefaultTest.java
index 8f7a413..9e4ced5 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAProcessorDefaultTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAProcessorDefaultTest.java
@@ -70,7 +70,12 @@ import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
import org.apache.olingo.odata2.jpa.processor.api.ODataJPATransaction;
import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping;
import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
+import org.apache.olingo.odata2.jpa.processor.core.mock.ODataContextMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.ODataServiceMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.data.SalesOrderHeader;
+import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmMappingImpl;
import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmTestModelView;
import org.easymock.EasyMock;
import org.junit.Assert;
@@ -130,10 +135,10 @@ public class ODataJPAProcessorDefaultTest extends JPAEdmTestModelView {
@Test
public void testExistsEntity() {
try {
- Assert.assertNotNull(objODataJPAProcessorDefault.existsEntity(getEntityCountCountUriInfo(),
+ Assert.assertNotNull(objODataJPAProcessorDefault.existsEntity(getEntityCountUriInfo(),
HttpContentType.APPLICATION_XML));
Assert.assertNull("ContentType MUST NOT set by entity provider", objODataJPAProcessorDefault.existsEntity(
- getEntityCountCountUriInfo(), HttpContentType.APPLICATION_XML).getHeader(STR_CONTENT_TYPE));
+ getEntityCountUriInfo(), HttpContentType.APPLICATION_XML).getHeader(STR_CONTENT_TYPE));
} catch (ODataException e) {
fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
} catch (Exception e) {
@@ -210,13 +215,15 @@ public class ODataJPAProcessorDefaultTest extends JPAEdmTestModelView {
return getLocalUriInfo();
}
- private GetEntityCountUriInfo getEntityCountCountUriInfo() {
+ private GetEntityCountUriInfo getEntityCountUriInfo() {
return getLocalUriInfo();
}
private DeleteUriInfo getDeletetUriInfo() {
UriInfo objUriInfo = EasyMock.createMock(UriInfo.class);
EasyMock.expect(objUriInfo.getStartEntitySet()).andStubReturn(getLocalEdmEntitySet());
+ List<NavigationSegment> navSegments = new ArrayList<NavigationSegment>();
+ EasyMock.expect(objUriInfo.getNavigationSegments()).andReturn(navSegments).anyTimes();
EasyMock.expect(objUriInfo.getTargetEntitySet()).andStubReturn(getLocalEdmEntitySet());
EasyMock.expect(objUriInfo.getSelect()).andStubReturn(null);
EasyMock.expect(objUriInfo.getOrderBy()).andStubReturn(getOrderByExpression());
@@ -241,6 +248,8 @@ public class ODataJPAProcessorDefaultTest extends JPAEdmTestModelView {
private UriInfo getLocalUriInfo() {
UriInfo objUriInfo = EasyMock.createMock(UriInfo.class);
EasyMock.expect(objUriInfo.getStartEntitySet()).andStubReturn(getLocalEdmEntitySet());
+ List<NavigationSegment> navSegments = new ArrayList<NavigationSegment>();
+ EasyMock.expect(objUriInfo.getNavigationSegments()).andReturn(navSegments).anyTimes();
EasyMock.expect(objUriInfo.getTargetEntitySet()).andStubReturn(getLocalEdmEntitySet());
EasyMock.expect(objUriInfo.getSelect()).andStubReturn(null);
EasyMock.expect(objUriInfo.getOrderBy()).andStubReturn(getOrderByExpression());
@@ -286,8 +295,7 @@ public class ODataJPAProcessorDefaultTest extends JPAEdmTestModelView {
EasyMock.expect(edmEntityType.hasStream()).andStubReturn(false);
EasyMock.expect(edmEntityType.getNavigationPropertyNames()).andStubReturn(new ArrayList<String>());
EasyMock.expect(edmEntityType.getKeyPropertyNames()).andStubReturn(new ArrayList<String>());
- EasyMock.expect(edmEntityType.getMapping()).andStubReturn(getEdmMappingMockedObj(SALES_ORDER));// ID vs Salesorder
- // ID
+ EasyMock.expect(edmEntityType.getMapping()).andStubReturn((EdmMapping) getEdmMappingMockedObj(SALES_ORDER));
EasyMock.replay(edmEntityType);
} catch (EdmException e) {
fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
@@ -317,6 +325,7 @@ public class ODataJPAProcessorDefaultTest extends JPAEdmTestModelView {
private ODataJPAContext getLocalmockODataJPAContext() {
ODataJPAContext odataJPAContext = EasyMock.createMock(ODataJPAContext.class);
+ EasyMock.expect(odataJPAContext.getPageSize()).andReturn(0).anyTimes();
EasyMock.expect(odataJPAContext.getPersistenceUnitName()).andStubReturn("salesorderprocessing");
EasyMock.expect(odataJPAContext.getEntityManagerFactory()).andStubReturn(mockEntityManagerFactory());
EasyMock.expect(odataJPAContext.getODataJPATransaction()).andStubReturn(getLocalJpaTransaction());
@@ -460,7 +469,7 @@ public class ODataJPAProcessorDefaultTest extends JPAEdmTestModelView {
EasyMock.expect(edmEntityType.getPropertyNames()).andStubReturn(getLocalPropertyNames());
EasyMock.expect(edmEntityType.getProperty(SO_ID)).andStubReturn(getEdmTypedMockedObj(SO_ID));
- EasyMock.expect(edmEntityType.getMapping()).andStubReturn(getEdmMappingMockedObj(SALES_ORDER));
+ EasyMock.expect(edmEntityType.getMapping()).andStubReturn((EdmMapping) getEdmMappingMockedObj(SALES_ORDER));
EasyMock.expect(edmEntityType.getKind()).andStubReturn(EdmTypeKind.SIMPLE);
EasyMock.expect(edmEntityType.getNamespace()).andStubReturn(SALES_ORDER_HEADERS);
@@ -500,7 +509,7 @@ public class ODataJPAProcessorDefaultTest extends JPAEdmTestModelView {
private EdmTyped getEdmTypedMockedObj(final String propertyName) {
EdmProperty mockedEdmProperty = EasyMock.createMock(EdmProperty.class);
try {
- EasyMock.expect(mockedEdmProperty.getMapping()).andStubReturn(getEdmMappingMockedObj(propertyName));
+ EasyMock.expect(mockedEdmProperty.getMapping()).andStubReturn((EdmMapping) getEdmMappingMockedObj(propertyName));
EdmType edmType = EasyMock.createMock(EdmType.class);
EasyMock.expect(edmType.getKind()).andStubReturn(EdmTypeKind.SIMPLE);
EasyMock.replay(edmType);
@@ -523,13 +532,15 @@ public class ODataJPAProcessorDefaultTest extends JPAEdmTestModelView {
return facets;
}
- private EdmMapping getEdmMappingMockedObj(final String propertyName) {
- EdmMapping mockedEdmMapping = EasyMock.createMock(EdmMapping.class);
+ private JPAEdmMapping getEdmMappingMockedObj(final String propertyName) {
+ JPAEdmMappingImpl mockedEdmMapping = EasyMock.createMock(JPAEdmMappingImpl.class);
if (propertyName.equalsIgnoreCase(SALES_ORDER)) {
- EasyMock.expect(mockedEdmMapping.getInternalName()).andStubReturn(SALES_ORDER_HEADERS);
+ EasyMock.expect(((EdmMapping) mockedEdmMapping).getInternalName()).andStubReturn(SALES_ORDER_HEADERS);
} else {
- EasyMock.expect(mockedEdmMapping.getInternalName()).andStubReturn(propertyName);
+ EasyMock.expect(((EdmMapping) mockedEdmMapping).getInternalName()).andStubReturn(propertyName);
}
+ EasyMock.expect(mockedEdmMapping.getODataJPATombstoneEntityListener()).andReturn(null);
+ EasyMock.<Class<?>> expect(mockedEdmMapping.getJPAType()).andReturn(SalesOrderHeader.class);
EasyMock.replay(mockedEdmMapping);
return mockedEdmMapping;
}
@@ -541,14 +552,16 @@ public class ODataJPAProcessorDefaultTest extends JPAEdmTestModelView {
}
private ODataContext getLocalODataContext() {
- ODataContext objODataContext = EasyMock.createMock(ODataContext.class);
+ ODataContext objODataContext = null;
try {
- EasyMock.expect(objODataContext.getPathInfo()).andStubReturn(getLocalPathInfo());
- EasyMock.expect(objODataContext.isInBatchMode()).andReturn(false).anyTimes();
+ ODataContextMock contextMock = new ODataContextMock();
+ contextMock.setODataService(new ODataServiceMock().mock());
+ contextMock.setPathInfo(getLocalPathInfo());
+ objODataContext = contextMock.mock();
+
} catch (ODataException e) {
fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
}
- EasyMock.replay(objODataContext);
return objODataContext;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb29fa48/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImplTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImplTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImplTest.java
index a62096b..4a00340 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImplTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAProcessorImplTest.java
@@ -167,6 +167,7 @@ public class JPAProcessorImplTest {
EasyMock.expect(objUriInfo.getFilter()).andStubReturn(getFilter());
EasyMock.expect(objUriInfo.getKeyPredicates()).andStubReturn(getKeyPredicates());
EasyMock.expect(objUriInfo.isLinks()).andStubReturn(false);
+ EasyMock.expect(objUriInfo.getNavigationSegments()).andReturn(new ArrayList<NavigationSegment>());
EasyMock.replay(objUriInfo);
return objUriInfo;
}
@@ -209,6 +210,7 @@ public class JPAProcessorImplTest {
private UriInfo getLocalUriInfo() {
UriInfo objUriInfo = EasyMock.createMock(UriInfo.class);
EasyMock.expect(objUriInfo.getStartEntitySet()).andStubReturn(getLocalEdmEntitySet());
+ EasyMock.expect(objUriInfo.getNavigationSegments()).andStubReturn(new ArrayList<NavigationSegment>());
EasyMock.expect(objUriInfo.getTargetEntitySet()).andStubReturn(getLocalEdmEntitySet());
EasyMock.expect(objUriInfo.getSelect()).andStubReturn(null);
EasyMock.expect(objUriInfo.getOrderBy()).andStubReturn(getOrderByExpression());
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb29fa48/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilderTest.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilderTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilderTest.java
new file mode 100644
index 0000000..4c9fbaa
--- /dev/null
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAQueryBuilderTest.java
@@ -0,0 +1,254 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.jpa.processor.core.access.data;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.api.uri.NavigationSegment;
+import org.apache.olingo.odata2.api.uri.UriInfo;
+import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetCountUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
+import org.apache.olingo.odata2.jpa.processor.api.ODataJPAQueryExtensionEntityListener;
+import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContextType;
+import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping;
+import org.apache.olingo.odata2.jpa.processor.core.access.data.JPAQueryBuilder.JPAQueryInfo;
+import org.apache.olingo.odata2.jpa.processor.core.access.data.JPAQueryBuilder.UriInfoType;
+import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
+import org.apache.olingo.odata2.jpa.processor.core.mock.ODataContextMock;
+import org.apache.olingo.odata2.jpa.processor.core.mock.ODataJPAContextMock;
+import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmMappingImpl;
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Test;
+
+public class JPAQueryBuilderTest {
+ JPAQueryBuilder builder = null;
+
+ @Before
+ public void setup() {
+ ODataContextMock odataContextMock = new ODataContextMock();
+ ODataContext context;
+ try {
+ context = odataContextMock.mock();
+ ODataJPAContext odataJPAContext = ODataJPAContextMock.mockODataJPAContext(context);
+ builder = new JPAQueryBuilder(odataJPAContext);
+ } catch (ODataException e) {
+ fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+ }
+ }
+
+ @Test
+ public void buildGetEntityTest() {
+ try {
+ assertNotNull(builder.build((GetEntityUriInfo) mockURIInfoWithListener(false)));
+ } catch (ODataException e) {
+ fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+ }
+ }
+
+ @Test
+ public void buildGetEntitySetTest() {
+ try {
+ JPAQueryInfo info = builder.build((GetEntitySetUriInfo) mockURIInfoWithListener(false));
+ assertNotNull(info.getQuery());
+ assertEquals(true, info.isTombstoneQuery());
+ } catch (ODataException e) {
+ fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+ }
+ }
+
+ @Test
+ public void buildDeleteEntityTest() {
+ try {
+ assertNotNull(builder.build((DeleteUriInfo) mockURIInfoWithListener(false)));
+ } catch (ODataException e) {
+ fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+ }
+ }
+
+ @Test
+ public void buildGetEntitySetCountTest() {
+ try {
+ assertNotNull(builder.build((GetEntitySetCountUriInfo) mockURIInfoWithListener(false)));
+ } catch (ODataException e) {
+ fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+ }
+ }
+
+ @Test
+ public void buildGetEntityCountTest() {
+ try {
+ assertNotNull(builder.build((GetEntityCountUriInfo) mockURIInfoWithListener(false)));
+ } catch (ODataException e) {
+ fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+ }
+ }
+
+ @Test
+ public void buildPutMergePatchTest() {
+ try {
+ assertNotNull(builder.build((PutMergePatchUriInfo) mockURIInfoWithListener(false)));
+ } catch (ODataException e) {
+ fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+ }
+ }
+
+ @Test
+ public void determineGetEntityTest() {
+ try {
+ assertEquals(JPQLContextType.JOIN_SINGLE, builder.determineJPQLContextType(mockURIInfoWithListener(true),
+ UriInfoType.GetEntity));
+ } catch (ODataException e) {
+ fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+ }
+ }
+
+ @Test
+ public void determineGetEntityCountTest() {
+ try {
+ assertEquals(JPQLContextType.JOIN_COUNT, builder.determineJPQLContextType(mockURIInfoWithListener(true),
+ UriInfoType.GetEntityCount));
+ } catch (ODataException e) {
+ fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+ }
+ }
+
+ @Test
+ public void determineGetEntitySetTest() {
+ try {
+ assertEquals(JPQLContextType.JOIN, builder.determineJPQLContextType(mockURIInfoWithListener(true),
+ UriInfoType.GetEntitySet));
+ } catch (ODataException e) {
+ fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+ }
+ }
+
+ @Test
+ public void determineGetEntitySetCountTest() {
+ try {
+ assertEquals(JPQLContextType.JOIN_COUNT, builder.determineJPQLContextType(mockURIInfoWithListener(true),
+ UriInfoType.GetEntitySetCount));
+ } catch (ODataException e) {
+ fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+ }
+ }
+
+ @Test
+ public void determinePutMergePatchTest() {
+ try {
+ assertEquals(JPQLContextType.JOIN_SINGLE, builder.determineJPQLContextType(mockURIInfoWithListener(true),
+ UriInfoType.PutMergePatch));
+ } catch (ODataException e) {
+ fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+ }
+ }
+
+ @Test
+ public void determineDeleteTest() {
+ try {
+ assertEquals(JPQLContextType.JOIN_SINGLE, builder.determineJPQLContextType(mockURIInfoWithListener(true),
+ UriInfoType.Delete));
+ } catch (ODataException e) {
+ fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+ }
+ }
+
+ private UriInfo mockURIInfoWithListener(boolean isNavigationEnabled) throws EdmException {
+ UriInfo uriInfo = EasyMock.createMock(UriInfo.class);
+ if (isNavigationEnabled) {
+ List<NavigationSegment> navSegments = new ArrayList<NavigationSegment>();
+ navSegments.add(null);
+ EasyMock.expect(uriInfo.getNavigationSegments()).andReturn(navSegments);
+ EasyMock.replay(uriInfo);
+ return uriInfo;
+ }
+ EdmEntityType edmEntityType = EasyMock.createMock(EdmEntityType.class);
+ EasyMock.expect(edmEntityType.getMapping()).andReturn((EdmMapping) mockEdmMapping());
+ EdmEntitySet edmEntitySet = EasyMock.createMock(EdmEntitySet.class);
+ EasyMock.expect(edmEntitySet.getEntityType()).andReturn(edmEntityType);
+ EasyMock.expect(uriInfo.getTargetEntitySet()).andReturn(edmEntitySet);
+ EasyMock.replay(edmEntityType, edmEntitySet, uriInfo);
+ return uriInfo;
+
+ }
+
+ private JPAEdmMapping mockEdmMapping() {
+ JPAEdmMappingImpl mockedEdmMapping = new JPAEdmMappingImpl();
+ mockedEdmMapping.setODataJPATombstoneEntityListener(JPAQueryExtensionMock.class);
+ return mockedEdmMapping;
+ }
+
+ public static final class JPAQueryExtensionMock extends ODataJPAQueryExtensionEntityListener {
+ Query query = EasyMock.createMock(Query.class);
+
+ @Override
+ public Query getQuery(GetEntityUriInfo uriInfo, EntityManager em) {
+ return query;
+ }
+
+ @Override
+ public Query getQuery(GetEntitySetUriInfo uriInfo, EntityManager em) {
+ return query;
+ }
+
+ @Override
+ public Query getQuery(GetEntitySetCountUriInfo uriInfo, EntityManager em) {
+ return query;
+ }
+
+ @Override
+ public Query getQuery(DeleteUriInfo uriInfo, EntityManager em) {
+ return query;
+ }
+
+ @Override
+ public Query getQuery(GetEntityCountUriInfo uriInfo, EntityManager em) {
+ return query;
+ }
+
+ @Override
+ public Query getQuery(PutMergePatchUriInfo uriInfo, EntityManager em) {
+ return query;
+ }
+
+ @Override
+ public boolean isTombstoneSupported() {
+ return false;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb29fa48/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataContextMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataContextMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataContextMock.java
index e39d3af..8d4fab1 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataContextMock.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataContextMock.java
@@ -28,6 +28,7 @@ public class ODataContextMock {
private ODataService odataService;
private PathInfo pathInfo;
+ private boolean isInBatchMode;
public void setODataService(final ODataService service) {
odataService = service;
@@ -37,6 +38,10 @@ public class ODataContextMock {
this.pathInfo = pathInfo;
}
+ public void isInBatchMode(final boolean isInBatchMode) {
+ this.isInBatchMode = isInBatchMode;
+ }
+
public ODataContext mock() throws ODataException {
ODataContext context = EasyMock.createMock(ODataContext.class);
EasyMock.expect(context.getService()).andReturn(odataService).anyTimes();
@@ -44,6 +49,7 @@ public class ODataContextMock {
ODataJPAServiceFactoryMock mockServiceFactory = new ODataJPAServiceFactoryMock(context);
mockServiceFactory.initializeODataJPAContext();
EasyMock.expect(context.getServiceFactory()).andReturn(mockServiceFactory).anyTimes();
+ EasyMock.expect(context.isInBatchMode()).andReturn(this.isInBatchMode).anyTimes();
EasyMock.replay(context);
return context;
}
@@ -52,6 +58,7 @@ public class ODataContextMock {
ODataContext context = EasyMock.createMock(ODataContext.class);
EasyMock.expect(context.getService()).andReturn(odataService).anyTimes();
EasyMock.expect(context.getPathInfo()).andReturn(pathInfo).anyTimes();
+ EasyMock.expect(context.isInBatchMode()).andReturn(this.isInBatchMode).anyTimes();
ODataJPAServiceFactoryMock mockServiceFactory = new ODataJPAServiceFactoryMock(context);
mockServiceFactory.initializeODataJPAContextX();
EasyMock.expect(context.getServiceFactory()).andReturn(mockServiceFactory).anyTimes();
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb29fa48/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAContextMock.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAContextMock.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAContextMock.java
index 433f784..9e03c86 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAContextMock.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/ODataJPAContextMock.java
@@ -54,6 +54,7 @@ public abstract class ODataJPAContextMock {
EasyMock.expect(odataJPAContext.getJPAEdmExtension()).andReturn(null);
EasyMock.expect(odataJPAContext.getDefaultNaming()).andReturn(true);
EasyMock.expect(odataJPAContext.getODataContext()).andReturn(context).anyTimes();
+ EasyMock.expect(odataJPAContext.getPageSize()).andReturn(0);
EasyMock.replay(odataJPAContext);
return odataJPAContext;
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb29fa48/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Customer.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Customer.java b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Customer.java
index bf5010b..0605956 100644
--- a/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Customer.java
+++ b/odata2-jpa-processor/jpa-ref/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/model/Customer.java
@@ -26,6 +26,7 @@ import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
+import javax.persistence.EntityListeners;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
@@ -34,6 +35,7 @@ import javax.persistence.Table;
@Entity
@Table(name = "T_CUSTOMER")
+@EntityListeners(org.apache.olingo.odata2.jpa.processor.ref.listeners.CustomerQueryExtension.class)
public class Customer extends CustomerBase {
@Id
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb29fa48/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/web/JPAReferenceServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/web/JPAReferenceServiceFactory.java b/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/web/JPAReferenceServiceFactory.java
index c264f70..fa499c8 100644
--- a/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/web/JPAReferenceServiceFactory.java
+++ b/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/web/JPAReferenceServiceFactory.java
@@ -46,6 +46,7 @@ public class JPAReferenceServiceFactory extends ODataJPAServiceFactory {
oDataJPAContext.setJPAEdmExtension(new SalesOrderProcessingExtension());
oDataJPAContext.setPageSize(PAGE_SIZE);
oDataJPAContext.setDefaultNaming(false);
+ oDataJPAContext.getODataContext().setDebugMode(true);
setErrorLevel();
setOnWriteJPAContent(onDBWriteContent);
return oDataJPAContext;