Repository: olingo-odata2 Updated Branches: refs/heads/master aedda7455 -> 7961a940c
[OLINGO-1192] Parameterizing JPA Queries Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/7961a940 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/7961a940 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/7961a940 Branch: refs/heads/master Commit: 7961a940cd83c7e9f08b1fb0b5da777be3d2e163 Parents: aedda74 Author: Archana Rai <[email protected]> Authored: Thu Oct 12 19:24:45 2017 +0530 Committer: Archana Rai <[email protected]> Committed: Thu Oct 12 19:24:45 2017 +0530 ---------------------------------------------------------------------- .../processor/core/ODataExpressionParser.java | 193 +++++++++++++++--- .../ODataParameterizedWhereExpressionUtil.java | 56 ++++++ .../core/access/data/JPAProcessorImpl.java | 36 ++++ .../core/access/data/JPAQueryBuilder.java | 30 ++- .../core/jpql/JPQLJoinSelectSingleContext.java | 4 +- .../JPQLJoinSelectSingleStatementBuilder.java | 4 + .../core/jpql/JPQLJoinStatementBuilder.java | 4 + .../processor/core/jpql/JPQLSelectContext.java | 16 +- .../jpql/JPQLSelectSingleStatementBuilder.java | 3 + .../core/jpql/JPQLSelectStatementBuilder.java | 4 + .../core/ODataFilterExpressionParserTest.java | 195 ++++++++++++++----- .../core/jpql/JPQLBuilderFactoryTest.java | 6 +- .../core/jpql/JPQLJoinContextTest.java | 6 +- .../jpql/JPQLJoinSelectSingleContextTest.java | 5 +- .../JPQLSelectSingleStatementBuilderTest.java | 24 ++- .../core/mock/ODataJPAContextMock.java | 4 +- 16 files changed, 501 insertions(+), 89 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/7961a940/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 4187ab0..a2266df 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 @@ -18,10 +18,15 @@ ******************************************************************************/ package org.apache.olingo.odata2.jpa.processor.core; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Time; import java.util.ArrayList; import java.util.Calendar; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import org.apache.olingo.odata2.api.edm.EdmException; import org.apache.olingo.odata2.api.edm.EdmLiteral; @@ -52,6 +57,7 @@ import org.apache.olingo.odata2.api.uri.expression.SortOrder; import org.apache.olingo.odata2.api.uri.expression.UnaryExpression; import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException; import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement; +import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmMappingImpl; /** * This class contains utility methods for parsing the filter expressions built by core library from user OData Query. @@ -63,7 +69,10 @@ public class ODataExpressionParser { public static final String EMPTY = ""; //$NON-NLS-1$ public static final ThreadLocal<Integer> methodFlag = new ThreadLocal<Integer>(); - + public static final Character[] EMPTY_CHARACTER_ARRAY = new Character[0]; + private static int index = 1; + private static Map<Integer, Object> positionalParameters = new HashMap<Integer, Object>(); + /** * This method returns the parsed where condition corresponding to the filter input in the user query. * @@ -91,6 +100,7 @@ public class ODataExpressionParser { return "-" + operand; //$NON-NLS-1$ } default: + reInitializePositionalParameters(); throw new ODataNotImplementedException(); } @@ -109,6 +119,7 @@ public class ODataExpressionParser { } } final String left = parseToJPAWhereExpression(binaryExpression.getLeftOperand(), tableAlias); + index++; final String right = parseToJPAWhereExpression(binaryExpression.getRightOperand(), tableAlias); // Special handling for STARTSWITH and ENDSWITH method expression @@ -116,6 +127,7 @@ public class ODataExpressionParser { if (!binaryExpression.getOperator().equals(BinaryOperator.EQ) && !(binaryExpression.getRightOperand() instanceof LiteralExpression) && ("true".equals(right) || "false".equals(right))) { + reInitializePositionalParameters(); throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.OPERATOR_EQ_NE_MISSING .addContent(binaryExpression.getOperator().toString()), null); } else if (binaryExpression.getOperator().equals(BinaryOperator.EQ)) { @@ -167,8 +179,10 @@ public class ODataExpressionParser { + JPQLStatement.Operator.GE + JPQLStatement.DELIMITER.SPACE + right + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT; case PROPERTY_ACCESS: + reInitializePositionalParameters(); throw new ODataNotImplementedException(); default: + reInitializePositionalParameters(); throw new ODataNotImplementedException(); } @@ -200,14 +214,16 @@ public class ODataExpressionParser { final LiteralExpression literal = (LiteralExpression) whereExpression; final EdmSimpleType literalType = (EdmSimpleType) literal.getEdmType(); EdmLiteral uriLiteral = EdmSimpleTypeKind.parseUriLiteral(literal.getUriLiteral()); - return evaluateComparingExpression(uriLiteral.getLiteral(), literalType); + return evaluateComparingExpression(uriLiteral.getLiteral(), literalType, null); case METHOD: final MethodExpression methodExpression = (MethodExpression) whereExpression; String first = parseToJPAWhereExpression(methodExpression.getParameters().get(0), tableAlias); + index++; String second = methodExpression.getParameterCount() > 1 ? parseToJPAWhereExpression(methodExpression.getParameters().get(1), tableAlias) : null; + index++; String third = methodExpression.getParameterCount() > 2 ? parseToJPAWhereExpression(methodExpression.getParameters().get(2), tableAlias) : null; @@ -219,12 +235,10 @@ public class ODataExpressionParser { case SUBSTRINGOF: if (methodFlag.get() != null && methodFlag.get() == 1) { methodFlag.set(null); - updateValueIfWildcards(first); return String.format("(CASE WHEN (%s LIKE CONCAT('%%',CONCAT(%s,'%%')) ESCAPE '\\') " + "THEN TRUE ELSE FALSE END)", second, first); } else { - first = updateValueIfWildcards(first); return String.format("(CASE WHEN (%s LIKE CONCAT('%%',CONCAT(%s,'%%')) ESCAPE '\\') " + "THEN TRUE ELSE FALSE END) = true", second, first); @@ -232,12 +246,11 @@ public class ODataExpressionParser { case TOLOWER: return String.format("LOWER(%s)", first); case STARTSWITH: - second = updateValueIfWildcards(second); return String.format("%s LIKE CONCAT(%s,'%%') ESCAPE '\\'", first, second); case ENDSWITH: - second = updateValueIfWildcards(second); return String.format("%s LIKE CONCAT('%%',%s) ESCAPE '\\'", first, second); default: + reInitializePositionalParameters(); throw new ODataNotImplementedException(); } @@ -245,8 +258,34 @@ public class ODataExpressionParser { throw new ODataNotImplementedException(); } } + + public static Map<Integer, Object> getPositionalParameters() { + return positionalParameters; + } + + public static void reInitializePositionalParameters() { + index = 1; + positionalParameters = new HashMap<Integer, Object>(); + } /** + * This method converts String to Byte array + * @param uriLiteral + */ + public static Byte[] toByteArray(String uriLiteral) { + int length = uriLiteral.length(); + if (length == 0) { + return new Byte[0]; + } + byte[] byteValues = uriLiteral.getBytes(); + final Byte[] result = new Byte[length]; + for (int i = 0; i < length; i++) { + result[i] = new Byte(byteValues[i]); + } + return result; + } + + /** * This method escapes the wildcards * @param first */ @@ -341,6 +380,7 @@ public class ODataExpressionParser { String literal = null; String propertyName = null; EdmSimpleType edmSimpleType = null; + Class<?> edmMappedType = null; StringBuilder keyFilters = new StringBuilder(); int i = 0; for (KeyPredicate keyPredicate : keyPredicates) { @@ -352,11 +392,12 @@ public class ODataExpressionParser { try { propertyName = keyPredicate.getProperty().getMapping().getInternalName(); edmSimpleType = (EdmSimpleType) keyPredicate.getProperty().getType(); + edmMappedType = ((JPAEdmMappingImpl)keyPredicate.getProperty().getMapping()).getJPAType(); } catch (EdmException e) { throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e); } - literal = evaluateComparingExpression(literal, edmSimpleType); + literal = evaluateComparingExpression(literal, edmSimpleType, edmMappedType); if (edmSimpleType == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance() || edmSimpleType == EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance()) { @@ -367,12 +408,32 @@ public class ODataExpressionParser { + JPQLStatement.Operator.EQ + JPQLStatement.DELIMITER.SPACE + literal); } if (keyFilters.length() > 0) { + Map<String, Map<Integer, Object>> parameterizedExpressionMap = + new HashMap<String, Map<Integer,Object>>(); + parameterizedExpressionMap.put(keyFilters.toString(), ODataExpressionParser.getPositionalParameters()); + ODataParameterizedWhereExpressionUtil.setParameterizedQueryMap(parameterizedExpressionMap); return keyFilters.toString(); } else { return null; } } - + + /** + * Convert char array to Character Array + * */ + public static Character[] toCharacterArray(char[] array) { + if (array == null) { + return null; + } else if (array.length == 0) { + return EMPTY_CHARACTER_ARRAY; + } + final Character[] result = new Character[array.length]; + for (int i = 0; i < array.length; i++) { + result[i] = new Character(array[i]); + } + return result; + } + public static String parseKeyPropertiesToJPAOrderByExpression( final List<EdmProperty> edmPropertylist, final String tableAlias) throws ODataJPARuntimeException { String propertyName = null; @@ -401,16 +462,25 @@ public class ODataExpressionParser { * * @param uriLiteral * @param edmSimpleType + * @param edmMappedType * @return the evaluated expression * @throws ODataJPARuntimeException */ - private static String evaluateComparingExpression(String uriLiteral, final EdmSimpleType edmSimpleType) - throws ODataJPARuntimeException { + private static String evaluateComparingExpression(String uriLiteral, final EdmSimpleType edmSimpleType, + Class<?> edmMappedType) throws ODataJPARuntimeException { if (EdmSimpleTypeKind.String.getEdmSimpleTypeInstance().isCompatible(edmSimpleType) || EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance().isCompatible(edmSimpleType)) { uriLiteral = uriLiteral.replaceAll("'", "''"); - uriLiteral = "'" + uriLiteral + "'"; //$NON-NLS-1$ //$NON-NLS-2$ + uriLiteral = updateValueIfWildcards(uriLiteral); + if (!positionalParameters.containsKey(index)) { + if(edmMappedType != null){ + evaluateExpressionForString(uriLiteral, edmMappedType); + }else{ + positionalParameters.put(index, String.valueOf(uriLiteral)); + } + } + uriLiteral = "?" + index; } else if (EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance().isCompatible(edmSimpleType) || EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance().isCompatible(edmSimpleType)) { try { @@ -418,19 +488,10 @@ public class ODataExpressionParser { (Calendar) edmSimpleType.valueOfString(uriLiteral, EdmLiteralKind.DEFAULT, null, edmSimpleType .getDefaultType()); - String year = String.format("%04d", datetime.get(Calendar.YEAR)); - String month = String.format("%02d", datetime.get(Calendar.MONTH) + 1); - String day = String.format("%02d", datetime.get(Calendar.DAY_OF_MONTH)); - String hour = String.format("%02d", datetime.get(Calendar.HOUR_OF_DAY)); - String min = String.format("%02d", datetime.get(Calendar.MINUTE)); - String sec = String.format("%02d", datetime.get(Calendar.SECOND)); - - uriLiteral = - JPQLStatement.DELIMITER.LEFT_BRACE + JPQLStatement.KEYWORD.TIMESTAMP + JPQLStatement.DELIMITER.SPACE + "\'" - + year + JPQLStatement.DELIMITER.HYPHEN + month + JPQLStatement.DELIMITER.HYPHEN + day - + JPQLStatement.DELIMITER.SPACE + hour + JPQLStatement.DELIMITER.COLON + min - + JPQLStatement.DELIMITER.COLON + sec + JPQLStatement.KEYWORD.OFFSET + "\'" - + JPQLStatement.DELIMITER.RIGHT_BRACE; + if (!positionalParameters.containsKey(index)) { + positionalParameters.put(index, datetime); + } + uriLiteral = "?" + index; } catch (EdmSimpleTypeException e) { throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e); @@ -445,20 +506,94 @@ public class ODataExpressionParser { String hourValue = String.format("%02d", time.get(Calendar.HOUR_OF_DAY)); String minValue = String.format("%02d", time.get(Calendar.MINUTE)); String secValue = String.format("%02d", time.get(Calendar.SECOND)); - + uriLiteral = - "\'" + hourValue + JPQLStatement.DELIMITER.COLON + minValue + JPQLStatement.DELIMITER.COLON + secValue - + "\'"; + hourValue + JPQLStatement.DELIMITER.COLON + minValue + JPQLStatement.DELIMITER.COLON + secValue; + if (!positionalParameters.containsKey(index)) { + positionalParameters.put(index, Time.valueOf(uriLiteral)); + } + uriLiteral = "?" + index; } catch (EdmSimpleTypeException e) { throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e); } - } else if (Long.class.equals(edmSimpleType.getDefaultType())) { - uriLiteral = uriLiteral + JPQLStatement.DELIMITER.LONG; //$NON-NLS-1$ + } else { + uriLiteral = evaluateExpressionForNumbers(uriLiteral, edmSimpleType, edmMappedType); } return uriLiteral; } + private static String evaluateExpressionForNumbers(String uriLiteral, EdmSimpleType edmSimpleType, + Class<?> edmMappedType) { + Class<? extends Object> type = edmMappedType==null? edmSimpleType.getDefaultType(): + edmMappedType; + if (Long.class.equals(type)) { + if (!positionalParameters.containsKey(index)) { + positionalParameters.put(index, Long.valueOf(uriLiteral)); + } + uriLiteral = "?" + index; + } else if (Double.class.equals(type)) { + if (!positionalParameters.containsKey(index)) { + positionalParameters.put(index, Double.valueOf(uriLiteral)); + } + uriLiteral = "?" + index; + } else if (Integer.class.equals(type)) { + if (!positionalParameters.containsKey(index)) { + positionalParameters.put(index, Integer.valueOf(uriLiteral)); + } + uriLiteral = "?" + index; + } else if (Byte.class.equals(type)) { + if (!positionalParameters.containsKey(index)) { + positionalParameters.put(index, Byte.valueOf(uriLiteral)); + } + uriLiteral = "?" + index; + } else if (Byte[].class.equals(type)) { + if (!positionalParameters.containsKey(index)) { + positionalParameters.put(index, toByteArray(uriLiteral)); + } + uriLiteral = "?" + index; + } else if (Short.class.equals(type)) { + if (!positionalParameters.containsKey(index)) { + positionalParameters.put(index, Short.valueOf(uriLiteral)); + } + uriLiteral = "?" + index; + } else if (BigDecimal.class.equals(type)) { + if (!positionalParameters.containsKey(index)) { + positionalParameters.put(index, new BigDecimal(uriLiteral)); + } + uriLiteral = "?" + index; + } else if (BigInteger.class.equals(type)) { + if (!positionalParameters.containsKey(index)) { + positionalParameters.put(index, new BigInteger(uriLiteral)); + } + uriLiteral = "?" + index; + } else if (Float.class.equals(type)) { + if (!positionalParameters.containsKey(index)) { + positionalParameters.put(index, Float.valueOf(uriLiteral)); + } + uriLiteral = "?" + index; + } + return uriLiteral; + } + + private static void evaluateExpressionForString(String uriLiteral, Class<?> edmMappedType) { + + if(edmMappedType.equals(char[].class)){ + positionalParameters.put(index, uriLiteral.toCharArray()); + }else if(edmMappedType.equals(char.class)){ + positionalParameters.put(index, uriLiteral.charAt(0)); + }else if(edmMappedType.equals(Character[].class)){ + char[] charArray = uriLiteral.toCharArray(); + Character[] charObjectArray =toCharacterArray(charArray); + positionalParameters.put(index, charObjectArray); + }else if(edmMappedType.equals(Character.class)){ + positionalParameters.put(index, (Character)uriLiteral.charAt(0)); + }else { + positionalParameters.put(index, String.valueOf(uriLiteral)); + } + + } + private static String getPropertyName(final CommonExpression whereExpression) throws EdmException, ODataJPARuntimeException { EdmTyped edmProperty = ((PropertyExpression) whereExpression).getEdmProperty(); http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/7961a940/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataParameterizedWhereExpressionUtil.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataParameterizedWhereExpressionUtil.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataParameterizedWhereExpressionUtil.java new file mode 100644 index 0000000..2ba6026 --- /dev/null +++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataParameterizedWhereExpressionUtil.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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; + +import java.util.HashMap; +import java.util.Map; + +public class ODataParameterizedWhereExpressionUtil { + /** + * Map includes where expression clause as the key and the + * ODataParameterizedWhereExpression as the value + */ + private static Map<String, Map<Integer, Object>> parameterizedQueryMap = new + HashMap<String, Map<Integer,Object>>(); + + private static String jpqlStatement = null; + + /** + * @return the parameterizedQueryMap + */ + public static Map<String, Map<Integer, Object>> getParameterizedQueryMap() { + return parameterizedQueryMap; + } + + /** + * @param parameterizedQueryMap the parameterizedQueryMap to set + */ + public static void setParameterizedQueryMap(Map<String, Map<Integer, Object>> parameterizedQueryMap) { + ODataParameterizedWhereExpressionUtil.parameterizedQueryMap = parameterizedQueryMap; + } + + public static void setJPQLStatement(String jpqlStatement) { + ODataParameterizedWhereExpressionUtil.jpqlStatement = jpqlStatement; + } + + public static String getJPQLStatement() { + return jpqlStatement; + } + +} http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/7961a940/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 195153b..6920c8f 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 @@ -21,12 +21,17 @@ package org.apache.olingo.odata2.jpa.processor.core.access.data; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.sql.Time; +import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Calendar; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import javax.persistence.EntityManager; import javax.persistence.Query; +import javax.persistence.TemporalType; import org.apache.olingo.odata2.api.commons.InlineCount; import org.apache.olingo.odata2.api.edm.EdmEntitySet; @@ -59,6 +64,7 @@ import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeExcep 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.ODataEntityParser; +import org.apache.olingo.odata2.jpa.processor.core.ODataParameterizedWhereExpressionUtil; import org.apache.olingo.odata2.jpa.processor.core.access.data.JPAPage.JPAPageBuilder; import org.apache.olingo.odata2.jpa.processor.core.access.data.JPAQueryBuilder.JPAQueryInfo; @@ -146,6 +152,7 @@ public class JPAProcessorImpl implements JPAProcessor { JPAQueryBuilder queryBuilder = new JPAQueryBuilder(oDataJPAContext); JPAQueryInfo queryInfo = queryBuilder.build(uriParserResultView); Query query = queryInfo.getQuery(); + setPositionalParametersToQuery(query); ODataJPATombstoneEntityListener listener = queryBuilder.getODataJPATombstoneEntityListener((UriInfo) uriParserResultView); Map<String, String> customQueryOptions = uriParserResultView.getCustomQueryOptions(); @@ -180,6 +187,33 @@ public class JPAProcessorImpl implements JPAProcessor { } } + /** + * @param query + */ + private void setPositionalParametersToQuery(Query query) { + Map<String, Map<Integer, Object>> parameterizedMap = ODataParameterizedWhereExpressionUtil. + getParameterizedQueryMap(); + if (parameterizedMap != null && parameterizedMap.size() > 0) { + for (Entry<String, Map<Integer, Object>> parameterEntry : parameterizedMap.entrySet()) { + if (ODataParameterizedWhereExpressionUtil.getJPQLStatement().contains(parameterEntry.getKey())) { + Map<Integer, Object> positionalParameters = parameterEntry.getValue(); + for (Entry<Integer, Object> param : positionalParameters.entrySet()) { + if (param.getValue() instanceof Calendar || param.getValue() instanceof Timestamp) { + query.setParameter(param.getKey(), (Calendar) param.getValue(), TemporalType.TIMESTAMP); + } else if (param.getValue() instanceof Time) { + query.setParameter(param.getKey(), (Time) param.getValue(), TemporalType.TIME); + } else { + query.setParameter(param.getKey(), param.getValue()); + } + } + parameterizedMap.remove(parameterEntry.getKey()); + ODataParameterizedWhereExpressionUtil.setJPQLStatement(null); + break; + } + } + } + } + /* Process Get Entity Request (Read) */ @Override public <T> Object process(GetEntityUriInfo uriParserResultView) @@ -194,6 +228,7 @@ public class JPAProcessorImpl implements JPAProcessor { JPAQueryBuilder queryBuilder = new JPAQueryBuilder(oDataJPAContext); Query query = queryBuilder.build(resultsView); + setPositionalParametersToQuery(query); List<?> resultList = query.getResultList(); if (resultList != null && resultList.size() == 1) { return Long.valueOf(resultList.get(0).toString()); @@ -208,6 +243,7 @@ public class JPAProcessorImpl implements JPAProcessor { JPAQueryBuilder queryBuilder = new JPAQueryBuilder(oDataJPAContext); Query query = queryBuilder.build(resultsView); + setPositionalParametersToQuery(query); List<?> resultList = query.getResultList(); if (resultList != null && resultList.size() == 1) { return Long.valueOf(resultList.get(0).toString()); http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/7961a940/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 index 232e90c..3319fc3 100644 --- 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 @@ -18,14 +18,19 @@ ******************************************************************************/ package org.apache.olingo.odata2.jpa.processor.core.access.data; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.persistence.EntityManager; import javax.persistence.Query; +import javax.persistence.TemporalType; import javax.persistence.metamodel.Attribute; import javax.persistence.metamodel.EntityType; @@ -46,6 +51,7 @@ 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.ODataParameterizedWhereExpressionUtil; public class JPAQueryBuilder { @@ -180,7 +186,29 @@ public class JPAQueryBuilder { JPQLContext jpqlContext = buildJPQLContext(contextType, uriParserResultView); JPQLStatement jpqlStatement = JPQLStatement.createBuilder(jpqlContext).build(); - return em.createQuery(normalizeMembers(em, jpqlStatement.toString())); + Query query = em.createQuery(normalizeMembers(em, jpqlStatement.toString())); + Map<String, Map<Integer, Object>> parameterizedMap = ODataParameterizedWhereExpressionUtil. + getParameterizedQueryMap(); + if (parameterizedMap != null && parameterizedMap.size() > 0) { + for (Entry<String, Map<Integer, Object>> parameterEntry : parameterizedMap.entrySet()) { + if (jpqlStatement.toString().contains(parameterEntry.getKey())) { + Map<Integer, Object> positionalParameters = parameterEntry.getValue(); + for (Entry<Integer, Object> param : positionalParameters.entrySet()) { + if (param.getValue() instanceof Calendar || param.getValue() instanceof Timestamp) { + query.setParameter(param.getKey(), (Calendar) param.getValue(), TemporalType.TIMESTAMP); + } else if (param.getValue() instanceof Time) { + query.setParameter(param.getKey(), (Time) param.getValue(), TemporalType.TIME); + } else { + query.setParameter(param.getKey(), param.getValue()); + } + } + parameterizedMap.remove(parameterEntry.getKey()); + ODataParameterizedWhereExpressionUtil.setJPQLStatement(null); + break; + } + } + } + return query; } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/7961a940/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinSelectSingleContext.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinSelectSingleContext.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinSelectSingleContext.java index 56b1686..3ebf1c6 100644 --- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinSelectSingleContext.java +++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinSelectSingleContext.java @@ -62,7 +62,9 @@ public class JPQLJoinSelectSingleContext extends JPQLSelectSingleContext impleme setKeyPredicates(entityView.getKeyPredicates()); setSelectExpression(generateSelectExpression()); - + + ODataExpressionParser.reInitializePositionalParameters(); + } catch (EdmException e) { throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL, e); } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/7961a940/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinSelectSingleStatementBuilder.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinSelectSingleStatementBuilder.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinSelectSingleStatementBuilder.java index 4c64855..da66916 100644 --- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinSelectSingleStatementBuilder.java +++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinSelectSingleStatementBuilder.java @@ -26,6 +26,8 @@ import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContextView; import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLJoinSelectSingleContextView; import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement; import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement.JPQLStatementBuilder; +import org.apache.olingo.odata2.jpa.processor.core.ODataExpressionParser; +import org.apache.olingo.odata2.jpa.processor.core.ODataParameterizedWhereExpressionUtil; public class JPQLJoinSelectSingleStatementBuilder extends JPQLStatementBuilder { @@ -39,6 +41,8 @@ public class JPQLJoinSelectSingleStatementBuilder extends JPQLStatementBuilder { @Override public JPQLStatement build() throws ODataJPARuntimeException { jpqlStatement = createStatement(createJPQLQuery()); + ODataParameterizedWhereExpressionUtil.setJPQLStatement(jpqlStatement.toString()); + ODataExpressionParser.reInitializePositionalParameters(); return jpqlStatement; } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/7961a940/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinStatementBuilder.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinStatementBuilder.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinStatementBuilder.java index c2e3085..4e87f05 100644 --- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinStatementBuilder.java +++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinStatementBuilder.java @@ -27,6 +27,8 @@ import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContextView; import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLJoinContextView; import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement; import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement.JPQLStatementBuilder; +import org.apache.olingo.odata2.jpa.processor.core.ODataExpressionParser; +import org.apache.olingo.odata2.jpa.processor.core.ODataParameterizedWhereExpressionUtil; public class JPQLJoinStatementBuilder extends JPQLStatementBuilder { @@ -40,6 +42,8 @@ public class JPQLJoinStatementBuilder extends JPQLStatementBuilder { @Override public JPQLStatement build() throws ODataJPARuntimeException { jpqlStatement = createStatement(createJPQLQuery()); + ODataParameterizedWhereExpressionUtil.setJPQLStatement(jpqlStatement.toString()); + ODataExpressionParser.reInitializePositionalParameters(); return jpqlStatement; } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/7961a940/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectContext.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectContext.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectContext.java index 34f8655..33921f4 100644 --- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectContext.java +++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectContext.java @@ -18,6 +18,9 @@ ******************************************************************************/ package org.apache.olingo.odata2.jpa.processor.core.jpql; +import java.util.HashMap; +import java.util.Map; + import org.apache.olingo.odata2.api.edm.EdmEntityType; import org.apache.olingo.odata2.api.edm.EdmException; import org.apache.olingo.odata2.api.edm.EdmMapping; @@ -29,6 +32,7 @@ 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.JPQLSelectContextView; import org.apache.olingo.odata2.jpa.processor.core.ODataExpressionParser; +import org.apache.olingo.odata2.jpa.processor.core.ODataParameterizedWhereExpressionUtil; public class JPQLSelectContext extends JPQLContext implements JPQLSelectContextView { @@ -154,10 +158,18 @@ public class JPQLSelectContext extends JPQLContext implements JPQLSelectContextV */ protected String generateWhereExpression() throws ODataException { if (entitySetView.getFilter() != null) { - return ODataExpressionParser.parseToJPAWhereExpression(entitySetView.getFilter(), getJPAEntityAlias()); + String whereExpression = ODataExpressionParser.parseToJPAWhereExpression( + entitySetView.getFilter(), getJPAEntityAlias()); + Map<String, Map<Integer, Object>> parameterizedExpressionMap = + new HashMap<String, Map<Integer,Object>>(); + parameterizedExpressionMap.put(whereExpression, ODataExpressionParser.getPositionalParameters()); + ODataParameterizedWhereExpressionUtil.setParameterizedQueryMap(parameterizedExpressionMap); + ODataExpressionParser.reInitializePositionalParameters(); + return whereExpression; } + ODataExpressionParser.reInitializePositionalParameters(); return null; } } -} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/7961a940/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectSingleStatementBuilder.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectSingleStatementBuilder.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectSingleStatementBuilder.java index 47e3f42..e1b0910 100644 --- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectSingleStatementBuilder.java +++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectSingleStatementBuilder.java @@ -24,6 +24,7 @@ import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLSelectSingleContextVi import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement; import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement.JPQLStatementBuilder; import org.apache.olingo.odata2.jpa.processor.core.ODataExpressionParser; +import org.apache.olingo.odata2.jpa.processor.core.ODataParameterizedWhereExpressionUtil; public class JPQLSelectSingleStatementBuilder extends JPQLStatementBuilder { @@ -37,6 +38,8 @@ public class JPQLSelectSingleStatementBuilder extends JPQLStatementBuilder { @Override public JPQLStatement build() throws ODataJPARuntimeException { jpqlStatement = createStatement(createJPQLQuery()); + ODataParameterizedWhereExpressionUtil.setJPQLStatement(jpqlStatement.toString()); + ODataExpressionParser.reInitializePositionalParameters(); return jpqlStatement; } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/7961a940/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectStatementBuilder.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectStatementBuilder.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectStatementBuilder.java index 49ed28b..1276238 100644 --- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectStatementBuilder.java +++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectStatementBuilder.java @@ -24,6 +24,8 @@ import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContextView; import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLSelectContextView; import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement; import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement.JPQLStatementBuilder; +import org.apache.olingo.odata2.jpa.processor.core.ODataExpressionParser; +import org.apache.olingo.odata2.jpa.processor.core.ODataParameterizedWhereExpressionUtil; public class JPQLSelectStatementBuilder extends JPQLStatementBuilder { @@ -37,6 +39,8 @@ public class JPQLSelectStatementBuilder extends JPQLStatementBuilder { @Override public JPQLStatement build() throws ODataJPARuntimeException { jpqlStatement = createStatement(createJPQLQuery()); + ODataParameterizedWhereExpressionUtil.setJPQLStatement(jpqlStatement.toString()); + ODataExpressionParser.reInitializePositionalParameters(); return jpqlStatement; } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/7961a940/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataFilterExpressionParserTest.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataFilterExpressionParserTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataFilterExpressionParserTest.java index c65dced..02baae6 100644 --- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataFilterExpressionParserTest.java +++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataFilterExpressionParserTest.java @@ -23,6 +23,10 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.InputStream; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Map; +import java.util.Map.Entry; import org.apache.olingo.odata2.api.edm.Edm; import org.apache.olingo.odata2.api.edm.EdmException; @@ -33,6 +37,7 @@ import org.apache.olingo.odata2.api.exception.ODataMessageException; import org.apache.olingo.odata2.api.uri.UriParser; import org.apache.olingo.odata2.api.uri.expression.ExpressionParserException; import org.apache.olingo.odata2.api.uri.expression.FilterExpression; +import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement; import org.junit.BeforeClass; import org.junit.Test; @@ -49,11 +54,11 @@ public class ODataFilterExpressionParserTest { private static final String[] EXPRESSION_BINARY_AND = { "id le '123' and soId eq 123L and not (substringof(id,'123') eq false) eq true", - "(((E1.id <= '123') AND (E1.soId = 123L)) AND (NOT(((CASE WHEN ('123' LIKE CONCAT('%',CONCAT(E1.id,'%')" + "(((E1.id <= '123') AND (E1.soId = 123)) AND (NOT(((CASE WHEN ('123' LIKE CONCAT('%',CONCAT(E1.id,'%')" + ") ESCAPE '\\') " + "THEN TRUE ELSE FALSE END) = false)) = true))" }; private static final String[] EXPRESSION_BINARY_OR = { "id ge '123' or soId gt 123L", - "((E1.id >= '123') OR (E1.soId > 123L))" }; + "((E1.id >= '123') OR (E1.soId > 123))" }; private static final String[] EXPRESSION_MEMBER_OR = { "id lt '123' or oValue/Currency eq 'INR'", "((E1.id < '123') OR (E1.oValue.Currency = 'INR'))" }; private static final String[] EXPRESSION_STARTS_WITH = { "startswith(oValue/Currency,'INR')", @@ -94,7 +99,7 @@ public class ODataFilterExpressionParserTest { "id eq '123' and id ne '123' or (id eq '123' and id ne '123')", "(((E1.id = '123') AND (E1.id <> '123')) OR ((E1.id = '123') AND (E1.id <> '123')))" }; private static final String[] EXPRESSION_DATETIME = { "date eq datetime'2000-01-01T00:00:00'", - "(E1.date = {ts '2000-01-01 00:00:00.000'})" }; + "(E1.date = 2000-01-01 00:00:00.000)" }; private static final String[] EXPRESSION_NULL = { "date eq null", "(E1.date IS null)" }; @@ -140,35 +145,45 @@ public class ODataFilterExpressionParserTest { @Test public void testDateTime() { - assertEquals(EXPRESSION_DATETIME[OUTPUT], parseWhereExpression( - EXPRESSION_DATETIME[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_DATETIME[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_DATETIME[OUTPUT], whereExpression); } @Test public void testPrecedence() { - assertEquals(EXPRESSION_PRECEDENCE[OUTPUT], parseWhereExpression( - EXPRESSION_PRECEDENCE[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_PRECEDENCE[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_PRECEDENCE[OUTPUT], whereExpression); } @Test public void testSubStringOfSQLInjection() { - assertEquals(EXPRESSION_SUBSTRINGOF_INJECTION1[OUTPUT], parseWhereExpression( - EXPRESSION_SUBSTRINGOF_INJECTION1[INPUT], false)); - assertEquals(EXPRESSION_SUBSTRINGOF_INJECTION2[OUTPUT], parseWhereExpression( - EXPRESSION_SUBSTRINGOF_INJECTION2[INPUT], false)); - assertEquals(EXPRESSION_SUBSTRINGOF_INJECTION3[OUTPUT], parseWhereExpression( - EXPRESSION_SUBSTRINGOF_INJECTION3[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_SUBSTRINGOF_INJECTION1[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_SUBSTRINGOF_INJECTION1[OUTPUT], whereExpression); + + whereExpression = parseWhereExpression(EXPRESSION_SUBSTRINGOF_INJECTION2[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_SUBSTRINGOF_INJECTION2[OUTPUT], whereExpression); + + whereExpression = parseWhereExpression(EXPRESSION_SUBSTRINGOF_INJECTION3[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_SUBSTRINGOF_INJECTION3[OUTPUT], whereExpression); } @Test public void testEndsWithSQLInjection() { - assertEquals(EXPRESSION_ENDSWITH_INJECTION1[OUTPUT], parseWhereExpression( - EXPRESSION_ENDSWITH_INJECTION1[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_ENDSWITH_INJECTION1[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_ENDSWITH_INJECTION1[OUTPUT], whereExpression); } @Test public void testSubStringWithAllOperator() { - assertEquals(EXPRESSION_SUBSTRING_ALL_OP[OUTPUT], parseWhereExpression(EXPRESSION_SUBSTRING_ALL_OP[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_SUBSTRING_ALL_OP[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_SUBSTRING_ALL_OP[OUTPUT], whereExpression); } @Test @@ -178,73 +193,101 @@ public class ODataFilterExpressionParserTest { @Test public void testSubStringOf() { - assertEquals(EXPRESSION_SUBSTRING_OF[OUTPUT], parseWhereExpression(EXPRESSION_SUBSTRING_OF[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_SUBSTRING_OF[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_SUBSTRING_OF[OUTPUT], whereExpression); } @Test public void testStartsWithEqual() { - assertEquals(EXPRESSION_STARTS_WITH_EQUAL[OUTPUT], parseWhereExpression(EXPRESSION_STARTS_WITH_EQUAL[INPUT], - false)); + String whereExpression = parseWhereExpression(EXPRESSION_STARTS_WITH_EQUAL[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_STARTS_WITH_EQUAL[OUTPUT], whereExpression); } @Test public void testEscapeCharacters() { - assertEquals(EXPRESSION_ESCAPE[OUTPUT], parseWhereExpression(EXPRESSION_ESCAPE[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_ESCAPE[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_ESCAPE[OUTPUT], whereExpression); } @Test public void testNotEndsWithToLowerMethod() { - assertEquals(EXPRESSION_NOT_ENDS_WITH[OUTPUT], parseWhereExpression(EXPRESSION_NOT_ENDS_WITH[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_NOT_ENDS_WITH[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_NOT_ENDS_WITH[OUTPUT], whereExpression); } @Test public void testNestedMethod() { - assertEquals(EXPRESSION_NESTED_METHOD[OUTPUT], parseWhereExpression(EXPRESSION_NESTED_METHOD[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_NESTED_METHOD[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_NESTED_METHOD[OUTPUT], whereExpression); } @Test public void testNotStartsWith() { - assertEquals(EXPRESSION_NOT_STARTS_WITH[OUTPUT], parseWhereExpression(EXPRESSION_NOT_STARTS_WITH[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_NOT_STARTS_WITH[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_NOT_STARTS_WITH[OUTPUT], whereExpression); } @Test public void testStartsWith() { - assertEquals(EXPRESSION_STARTS_WITH[OUTPUT], parseWhereExpression(EXPRESSION_STARTS_WITH[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_STARTS_WITH[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_STARTS_WITH[OUTPUT], whereExpression); } @Test public void testSimpleEqRelation() { - assertEquals(EXPRESSION_EQ[OUTPUT], parseWhereExpression(EXPRESSION_EQ[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_EQ[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_EQ[OUTPUT], whereExpression); + } @Test public void testSimpleNeRelation() { - assertEquals(EXPRESSION_NE[OUTPUT], parseWhereExpression(EXPRESSION_NE[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_NE[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_NE[OUTPUT], whereExpression); } @Test public void testBinaryAnd() { - assertEquals(EXPRESSION_BINARY_AND[OUTPUT], parseWhereExpression(EXPRESSION_BINARY_AND[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_BINARY_AND[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_BINARY_AND[OUTPUT], whereExpression); } @Test public void testBinaryOr() { - assertEquals(EXPRESSION_BINARY_OR[OUTPUT], parseWhereExpression(EXPRESSION_BINARY_OR[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_BINARY_OR[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_BINARY_OR[OUTPUT], whereExpression); } @Test public void testMemberOr() { - assertEquals(EXPRESSION_MEMBER_OR[OUTPUT], parseWhereExpression(EXPRESSION_MEMBER_OR[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_MEMBER_OR[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_MEMBER_OR[OUTPUT], whereExpression); } @Test public void testNull() { - assertEquals(EXPRESSION_NULL[OUTPUT], parseWhereExpression(EXPRESSION_NULL[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_NULL[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_NULL[OUTPUT], whereExpression); } @Test public void testNotNull() { - assertEquals(EXPRESSION_NOT_NULL[OUTPUT], parseWhereExpression(EXPRESSION_NOT_NULL[INPUT], false)); + String whereExpression = parseWhereExpression(EXPRESSION_NOT_NULL[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_NOT_NULL[OUTPUT], whereExpression); } private String parseWhereExpression(final String input, final boolean isExceptionExpected) { @@ -271,48 +314,106 @@ public class ODataFilterExpressionParserTest { @Test public void testStartsWith_BinaryEq() { - assertEquals(EXPRESSION_STARTSWITH_EQBINARY[OUTPUT], parseWhereExpression( - EXPRESSION_STARTSWITH_EQBINARY[INPUT], false)); + String whereExpression = parseWhereExpression( + EXPRESSION_STARTSWITH_EQBINARY[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_STARTSWITH_EQBINARY[OUTPUT], whereExpression); } @Test public void testBinaryEq_StartsWith() { - assertEquals(EXPRESSION_EQBINARY_STARTSWITH[OUTPUT], parseWhereExpression( - EXPRESSION_EQBINARY_STARTSWITH[INPUT], false)); + String whereExpression = parseWhereExpression( + EXPRESSION_EQBINARY_STARTSWITH[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_EQBINARY_STARTSWITH[OUTPUT], whereExpression); } public void testStartsWithEq_BinaryEq() { - assertEquals(EXPRESSION_STARTSWITHEQ_EQBINARY[OUTPUT], parseWhereExpression( - EXPRESSION_STARTSWITHEQ_EQBINARY[INPUT], false)); + String whereExpression = parseWhereExpression( + EXPRESSION_STARTSWITHEQ_EQBINARY[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_STARTSWITHEQ_EQBINARY[OUTPUT], whereExpression); } @Test public void testBinaryEq_StartsWithEq() { - assertEquals(EXPRESSION_EQBINARY_STARTSWITHEQ[OUTPUT], parseWhereExpression( - EXPRESSION_EQBINARY_STARTSWITHEQ[INPUT], false)); + String whereExpression = parseWhereExpression( + EXPRESSION_EQBINARY_STARTSWITHEQ[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_EQBINARY_STARTSWITHEQ[OUTPUT], whereExpression); } @Test public void testStartsWith_StartsWith() { - assertEquals(EXPRESSION_STARTSWITH_STARTSWITH[OUTPUT], parseWhereExpression( - EXPRESSION_STARTSWITH_STARTSWITH[INPUT], false)); + String whereExpression = parseWhereExpression( + EXPRESSION_STARTSWITH_STARTSWITH[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_STARTSWITH_STARTSWITH[OUTPUT], whereExpression); } @Test public void testStartsWithEq_StartsWithEq() { - assertEquals(EXPRESSION_STARTSWITHEQ_STARTSWITHEQ[OUTPUT], parseWhereExpression( - EXPRESSION_STARTSWITHEQ_STARTSWITHEQ[INPUT], false)); + String whereExpression = parseWhereExpression( + EXPRESSION_STARTSWITHEQ_STARTSWITHEQ[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_STARTSWITHEQ_STARTSWITHEQ[OUTPUT], whereExpression); } @Test public void testStartsWithEq_AndTrue() { - assertEquals(EXPRESSION_STARTSWITHEQTRUE_ANDTRUE[OUTPUT], parseWhereExpression( - EXPRESSION_STARTSWITHEQTRUE_ANDTRUE[INPUT], false)); + String whereExpression = parseWhereExpression( + EXPRESSION_STARTSWITHEQTRUE_ANDTRUE[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_STARTSWITHEQTRUE_ANDTRUE[OUTPUT], whereExpression); } @Test public void testStarts_AndTrue() { - assertEquals(EXPRESSION_STARTSWITH_ANDTRUE[OUTPUT], parseWhereExpression( - EXPRESSION_STARTSWITH_ANDTRUE[INPUT], false)); + String whereExpression = parseWhereExpression( + EXPRESSION_STARTSWITH_ANDTRUE[INPUT], false); + whereExpression = replacePositionalParameters(whereExpression); + assertEquals(EXPRESSION_STARTSWITH_ANDTRUE[OUTPUT], whereExpression); + } + + private String replacePositionalParameters(String whereExpression) { + Map<Integer, Object> positionalParameters = ODataExpressionParser.getPositionalParameters(); + for (Entry<Integer, Object> param : positionalParameters.entrySet()) { + Integer key = param.getKey(); + if (param.getValue() instanceof String) { + whereExpression = whereExpression.replaceAll("\\?" + String.valueOf(key), "\'" + param.getValue() + "\'"); + } else if (param.getValue() instanceof Timestamp || param.getValue() instanceof Calendar){ + Calendar datetime = (Calendar) param.getValue(); + String year = String.format("%04d", datetime.get(Calendar.YEAR)); + String month = String.format("%02d", datetime.get(Calendar.MONTH) + 1); + String day = String.format("%02d", datetime.get(Calendar.DAY_OF_MONTH)); + String hour = String.format("%02d", datetime.get(Calendar.HOUR_OF_DAY)); + String min = String.format("%02d", datetime.get(Calendar.MINUTE)); + String sec = String.format("%02d", datetime.get(Calendar.SECOND)); + String value = + year + JPQLStatement.DELIMITER.HYPHEN + month + JPQLStatement.DELIMITER.HYPHEN + day + + JPQLStatement.DELIMITER.SPACE + hour + JPQLStatement.DELIMITER.COLON + min + + JPQLStatement.DELIMITER.COLON + sec + JPQLStatement.KEYWORD.OFFSET; + whereExpression = whereExpression.replaceAll("\\?" + String.valueOf(key), value); + } else if(param.getValue() instanceof Byte[]){ + byte[] byteValue = convertToByte((Byte[])param.getValue()); + whereExpression = whereExpression.replaceAll("\\?" + String.valueOf(key), new String(byteValue)); + }else { + whereExpression = whereExpression.replaceAll("\\?" + String.valueOf(key), param.getValue().toString()); + } + } + ODataExpressionParser.reInitializePositionalParameters(); + return whereExpression; } + + private byte[] convertToByte(Byte[] value) { + int length = value.length; + if (length == 0) { + return new byte[0]; + } + final byte[] result = new byte[length]; + for (int i = 0; i < length; i++) { + result[i] = value[i]; + } + return result; + } } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/7961a940/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLBuilderFactoryTest.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLBuilderFactoryTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLBuilderFactoryTest.java index 318c167..5aef018 100644 --- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLBuilderFactoryTest.java +++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLBuilderFactoryTest.java @@ -39,7 +39,6 @@ import javax.persistence.metamodel.Metamodel; 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.edm.EdmProperty; import org.apache.olingo.odata2.api.edm.EdmSimpleType; import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind; @@ -61,6 +60,7 @@ import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants; import org.apache.olingo.odata2.jpa.processor.core.factory.ODataJPAFactoryImpl; import org.apache.olingo.odata2.jpa.processor.core.jpql.JPQLSelectContext.JPQLSelectContextBuilder; import org.apache.olingo.odata2.jpa.processor.core.jpql.JPQLSelectSingleContext.JPQLSelectSingleContextBuilder; +import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmMappingImpl; import org.easymock.EasyMock; import org.junit.Test; @@ -181,9 +181,11 @@ public class JPQLBuilderFactoryTest { KeyPredicate keyPredicate = EasyMock.createMock(KeyPredicate.class); EdmProperty kpProperty = EasyMock.createMock(EdmProperty.class); EdmSimpleType edmType = EdmSimpleTypeKind.Int32.getEdmSimpleTypeInstance(); - EdmMapping edmMapping = EasyMock.createMock(EdmMapping.class); + JPAEdmMappingImpl edmMapping = EasyMock.createMock(JPAEdmMappingImpl.class); EasyMock.expect(edmMapping.getInternalName()).andStubReturn("Field1"); EasyMock.expect(keyPredicate.getLiteral()).andStubReturn("1"); + EasyMock.expect(edmMapping.getJPAType()) + .andStubReturn(null); try { EasyMock.expect(kpProperty.getName()).andStubReturn("Field1"); EasyMock.expect(kpProperty.getType()).andStubReturn(edmType); http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/7961a940/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinContextTest.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinContextTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinContextTest.java index 3c595ae..2fbedef 100644 --- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinContextTest.java +++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinContextTest.java @@ -44,6 +44,7 @@ import org.apache.olingo.odata2.jpa.processor.api.access.JPAJoinClause; 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.core.jpql.JPQLJoinSelectContext.JPQLJoinContextBuilder; +import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmMappingImpl; import org.easymock.EasyMock; import org.junit.After; import org.junit.AfterClass; @@ -70,6 +71,7 @@ public class JPQLJoinContextTest { final EdmNavigationProperty navigationProperty = createNavigationProperty("a"); final EdmNavigationProperty navigationProperty1 = createNavigationProperty("b"); final List<KeyPredicate> keyPredicates = createKeyPredicates(); + EdmProperty kpProperty = EasyMock.createMock(EdmProperty.class); NavigationSegment navigationSegment = new NavigationSegment() { @Override @@ -182,7 +184,9 @@ public class JPQLJoinContextTest { KeyPredicate keyPredicate = EasyMock.createMock(KeyPredicate.class); EasyMock.expect(keyPredicate.getLiteral()).andStubReturn("1"); EdmProperty edmProperty = EasyMock.createMock(EdmProperty.class); - EdmMapping edmMapping = EasyMock.createMock(EdmMapping.class); + JPAEdmMappingImpl edmMapping = EasyMock.createMock(JPAEdmMappingImpl.class); + EasyMock.expect(edmMapping.getJPAType()) + .andStubReturn(null); EasyMock.expect(edmMapping.getInternalName()).andStubReturn("soid"); EasyMock.expect(edmProperty.getMapping()).andStubReturn(edmMapping); EasyMock.expect(edmProperty.getName()).andStubReturn("soid"); http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/7961a940/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinSelectSingleContextTest.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinSelectSingleContextTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinSelectSingleContextTest.java index f16217c..d5684e0 100644 --- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinSelectSingleContextTest.java +++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLJoinSelectSingleContextTest.java @@ -44,6 +44,7 @@ import org.apache.olingo.odata2.jpa.processor.api.access.JPAJoinClause; 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.core.jpql.JPQLJoinSelectSingleContext.JPQLJoinSelectSingleContextBuilder; +import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmMappingImpl; import org.easymock.EasyMock; import org.junit.After; import org.junit.AfterClass; @@ -195,7 +196,9 @@ public class JPQLJoinSelectSingleContextTest { KeyPredicate keyPredicate = EasyMock.createMock(KeyPredicate.class); EasyMock.expect(keyPredicate.getLiteral()).andStubReturn("1"); EdmProperty edmProperty = EasyMock.createMock(EdmProperty.class); - EdmMapping edmMapping = EasyMock.createMock(EdmMapping.class); + JPAEdmMappingImpl edmMapping = EasyMock.createMock(JPAEdmMappingImpl.class); + EasyMock.expect(edmMapping.getJPAType()) + .andStubReturn(null); EasyMock.expect(edmMapping.getInternalName()).andStubReturn("soid"); EasyMock.expect(edmProperty.getMapping()).andStubReturn(edmMapping); EasyMock.expect(edmProperty.getName()).andStubReturn("soid"); http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/7961a940/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectSingleStatementBuilderTest.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectSingleStatementBuilderTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectSingleStatementBuilderTest.java index 9d47839..63b5948 100644 --- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectSingleStatementBuilderTest.java +++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/jpql/JPQLSelectSingleStatementBuilderTest.java @@ -23,11 +23,12 @@ import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; 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.edm.EdmProperty; import org.apache.olingo.odata2.api.edm.EdmSimpleType; import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind; @@ -39,6 +40,8 @@ import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeExcep import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContext; import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContext.JPQLContextBuilder; import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContextType; +import org.apache.olingo.odata2.jpa.processor.core.ODataParameterizedWhereExpressionUtil; +import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmMappingImpl; import org.easymock.EasyMock; import org.junit.Before; import org.junit.Test; @@ -69,7 +72,9 @@ public class JPQLSelectSingleStatementBuilderTest { KeyPredicate keyPredicate = EasyMock.createMock(KeyPredicate.class); EdmProperty kpProperty = EasyMock.createMock(EdmProperty.class); EdmSimpleType edmType = EdmSimpleTypeKind.Int32.getEdmSimpleTypeInstance(); - EdmMapping edmMapping = EasyMock.createMock(EdmMapping.class); + JPAEdmMappingImpl edmMapping = EasyMock.createMock(JPAEdmMappingImpl.class); + EasyMock.expect(edmMapping.getJPAType()) + .andStubReturn(null); EasyMock.expect(edmMapping.getInternalName()).andStubReturn("Field1"); EasyMock.expect(keyPredicate.getLiteral()).andStubReturn("1"); try { @@ -114,11 +119,22 @@ public class JPQLSelectSingleStatementBuilderTest { @Test public void testBuildSimpleQuery() throws EdmException, ODataJPARuntimeException { + JPQLSelectSingleContext JPQLSelectSingleContextImpl = createSelectContext(); JPQLSelectSingleStatementBuilder = new JPQLSelectSingleStatementBuilder(JPQLSelectSingleContextImpl); - assertEquals("SELECT E1 FROM SalesOrderHeader E1 WHERE E1.Field1 = 1", JPQLSelectSingleStatementBuilder.build() - .toString()); + String query = JPQLSelectSingleStatementBuilder.build().toString(); + query = query.substring(0, query.indexOf("?")); + Map<String, Map<Integer, Object>> positionalParameters = + ODataParameterizedWhereExpressionUtil.getParameterizedQueryMap(); + for (Entry<String, Map<Integer, Object>> param : positionalParameters.entrySet()) { + for (Entry<Integer, Object> postionalParam : param.getValue().entrySet()) { + query += postionalParam.getValue(); + } + } + + assertEquals("SELECT E1 FROM SalesOrderHeader E1 WHERE E1.Field1 = 1", query); + } } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/7961a940/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 cb59b6f..c218bfb 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 @@ -76,7 +76,9 @@ public abstract class ODataJPAContextMock { Query jpqlquery = EasyMock.createMock(Query.class); Capture<String> capturedArgument = new Capture<String>(); EasyMock.expect(em.createQuery(EasyMock.capture(capturedArgument))).andReturn(jpqlquery); - EasyMock.replay(em,mm); + EasyMock.expect(jpqlquery.setParameter(EasyMock.anyInt(), EasyMock.anyObject())) + .andReturn(jpqlquery).anyTimes(); + EasyMock.replay(em,mm,jpqlquery); return em; }
