[OLINGO-451] Support for StartsWith and EndsWith OData Methods in JPA processor
Signed-off-by: Chandan V A <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/edd8c064 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/edd8c064 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/edd8c064 Branch: refs/heads/Olingo-129_PocJpaDataStore Commit: edd8c0646d0552dd0ef46d076edfb3f87475fb66 Parents: 413bde2 Author: Chandan V A <[email protected]> Authored: Wed Nov 26 14:43:13 2014 +0530 Committer: Chandan V A <[email protected]> Committed: Wed Nov 26 14:43:13 2014 +0530 ---------------------------------------------------------------------- .../api/exception/ODataJPARuntimeException.java | 2 + .../processor/core/ODataExpressionParser.java | 44 ++++++++++++++++---- .../main/resources/jpaprocessor_msg.properties | 1 + 3 files changed, 38 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/edd8c064/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/exception/ODataJPARuntimeException.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/exception/ODataJPARuntimeException.java b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/exception/ODataJPARuntimeException.java index 9863544..0b9c3b2 100644 --- a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/exception/ODataJPARuntimeException.java +++ b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/exception/ODataJPARuntimeException.java @@ -70,6 +70,8 @@ public class ODataJPARuntimeException extends ODataJPAException { "ERROR_JPA_BLOB_NULL"); public static final MessageReference ERROR_JPA_CLOB_NULL = createMessageReference(ODataJPARuntimeException.class, "ERROR_JPA_CLOB_NULL"); + public static final MessageReference OPERATOR_EQ_NE_MISSING = createMessageReference(ODataJPARuntimeException.class, + "OPERATOR_EQ_NE_MISSING"); private ODataJPARuntimeException(final String localizedMessage, final Throwable e, final MessageReference msgRef) { super(localizedMessage, e, msgRef); http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/edd8c064/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataExpressionParser.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataExpressionParser.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataExpressionParser.java index 5510fde..8188a72 100644 --- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataExpressionParser.java +++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataExpressionParser.java @@ -61,7 +61,7 @@ import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement; public class ODataExpressionParser { public static final String EMPTY = ""; //$NON-NLS-1$ - public static Integer methodFlag = 0; + public static final ThreadLocal<Integer> methodFlag = new ThreadLocal<Integer>(); /** * This method returns the parsed where condition corresponding to the filter input in the user query. @@ -97,15 +97,34 @@ public class ODataExpressionParser { return parseToJPAWhereExpression(((FilterExpression) whereExpression).getExpression(), tableAlias); case BINARY: final BinaryExpression binaryExpression = (BinaryExpression) whereExpression; - if ((binaryExpression.getLeftOperand().getKind() == ExpressionKind.METHOD) - && ((binaryExpression.getOperator() == BinaryOperator.EQ) || - (binaryExpression.getOperator() == BinaryOperator.NE)) - && (((MethodExpression) binaryExpression.getLeftOperand()).getMethod() == MethodOperator.SUBSTRINGOF)) { - methodFlag = 1; + MethodOperator operator = null; + if (binaryExpression.getLeftOperand().getKind() == ExpressionKind.METHOD) { + operator = ((MethodExpression) binaryExpression.getLeftOperand()).getMethod(); + } + if (operator != null && ((binaryExpression.getOperator() == BinaryOperator.EQ) || + (binaryExpression.getOperator() == BinaryOperator.NE))) { + if (operator == MethodOperator.SUBSTRINGOF) { + methodFlag.set(1); + } } final String left = parseToJPAWhereExpression(binaryExpression.getLeftOperand(), tableAlias); final String right = parseToJPAWhereExpression(binaryExpression.getRightOperand(), tableAlias); + // Special handling for STARTSWITH and ENDSWITH method expression + if (operator != null && (operator == MethodOperator.STARTSWITH || operator == MethodOperator.ENDSWITH)) { + if (!binaryExpression.getOperator().equals(BinaryOperator.EQ)) { + throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.OPERATOR_EQ_NE_MISSING + .addContent(binaryExpression.getOperator().toString()), null); + } else if (right.equals("false")) { + return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left.replaceFirst("LIKE", "NOT LIKE") + + JPQLStatement.DELIMITER.SPACE + + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT; + } else { + return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left + + JPQLStatement.DELIMITER.SPACE + + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT; + } + } switch (binaryExpression.getOperator()) { case AND: return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left + JPQLStatement.DELIMITER.SPACE @@ -143,6 +162,7 @@ public class ODataExpressionParser { throw new ODataNotImplementedException(); default: throw new ODataNotImplementedException(); + } case PROPERTY: @@ -183,7 +203,7 @@ public class ODataExpressionParser { case METHOD: final MethodExpression methodExpression = (MethodExpression) whereExpression; String first = parseToJPAWhereExpression(methodExpression.getParameters().get(0), tableAlias); - final String second = + String second = methodExpression.getParameterCount() > 1 ? parseToJPAWhereExpression(methodExpression.getParameters().get(1), tableAlias) : null; String third = @@ -196,14 +216,20 @@ public class ODataExpressionParser { return String.format("SUBSTRING(%s, %s + 1 %s)", first, second, third); case SUBSTRINGOF: first = first.substring(1, first.length() - 1); - if (methodFlag == 1) { - methodFlag = 0; + if (methodFlag.get() == 1) { + methodFlag.set(0); return String.format("(CASE WHEN (%s LIKE '%%%s%%') THEN TRUE ELSE FALSE END)", second, first); } else { return String.format("(CASE WHEN (%s LIKE '%%%s%%') THEN TRUE ELSE FALSE END) = true", second, first); } case TOLOWER: return String.format("LOWER(%s)", first); + case STARTSWITH: + second = second.substring(1, second.length() - 1); + return String.format("%s LIKE '%s%%'", first, second); + case ENDSWITH: + second = second.substring(1, second.length() - 1); + return String.format("%s LIKE '%%%s'", first, second); default: throw new ODataNotImplementedException(); } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/edd8c064/odata2-jpa-processor/jpa-core/src/main/resources/jpaprocessor_msg.properties ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/main/resources/jpaprocessor_msg.properties b/odata2-jpa-processor/jpa-core/src/main/resources/jpaprocessor_msg.properties index 7788d49..29c1006 100644 --- a/odata2-jpa-processor/jpa-core/src/main/resources/jpaprocessor_msg.properties +++ b/odata2-jpa-processor/jpa-core/src/main/resources/jpaprocessor_msg.properties @@ -57,6 +57,7 @@ org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException.RE org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException.RESOURCE_X_NOT_FOUND="OData - JPA Runtime: Resource [%1$s] not found" org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException.ERROR_JPA_BLOB_NULL="OData - JPA Runtime: Blob data type is null. Initialize Blob type by implementing callback interface org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent. org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException.ERROR_JPA_CLOB_NULL="OData - JPA Runtime: Clob data type is null. Initialize Clob type by implementing callback interface org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent. +org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException.OPERATOR_EQ_NE_MISSING="OData - JPA Runtime: OData Expression parser - Operator EQ or NE missing" #JPA Common Errors org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAException.ODATA_JPACTX_NULL="OData JPA: OData JPA Context cannot be null"
