diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ExpressionEvaluatingParameterBinder.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ExpressionEvaluatingParameterBinder.java index 7c5d6c08a..83489e61b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ExpressionEvaluatingParameterBinder.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ExpressionEvaluatingParameterBinder.java @@ -45,7 +45,7 @@ import com.mongodb.util.JSON; /** * {@link ExpressionEvaluatingParameterBinder} allows to evaluate, convert and bind parameters to placeholders within a * {@link String}. - * + * * @author Christoph Strobl * @author Thomas Darimont * @author Oliver Gierke @@ -59,7 +59,7 @@ class ExpressionEvaluatingParameterBinder { /** * Creates new {@link ExpressionEvaluatingParameterBinder} - * + * * @param expressionParser must not be {@literal null}. * @param evaluationContextProvider must not be {@literal null}. */ @@ -76,7 +76,7 @@ class ExpressionEvaluatingParameterBinder { /** * Bind values provided by {@link MongoParameterAccessor} to placeholders in {@literal raw} while considering * potential conversions and parameter types. - * + * * @param raw can be {@literal null} or empty. * @param accessor must not be {@literal null}. * @param bindingContext must not be {@literal null}. @@ -93,7 +93,7 @@ class ExpressionEvaluatingParameterBinder { /** * Replaced the parameter placeholders with the actual parameter values from the given {@link ParameterBinding}s. - * + * * @param input must not be {@literal null} or empty. * @param accessor must not be {@literal null}. * @param bindingContext must not be {@literal null}. @@ -264,38 +264,34 @@ class ExpressionEvaluatingParameterBinder { */ private Placeholder extractPlaceholder(int parameterIndex, Matcher matcher) { - if (matcher.groupCount() > 1) { + String rawPlaceholder = matcher.group(parameterIndex * 3 + 1); + String suffix = matcher.group(parameterIndex * 3 + 2); - String rawPlaceholder = matcher.group(parameterIndex * 3 + 1); - String suffix = matcher.group(parameterIndex * 3 + 2); + if (!StringUtils.hasText(rawPlaceholder)) { - if (!StringUtils.hasText(rawPlaceholder)) { - - rawPlaceholder = matcher.group(); - if(rawPlaceholder.matches(".*\\d$")) { - suffix = ""; - } else { - int index = rawPlaceholder.replaceAll("[^\\?0-9]*$", "").length() - 1; - if (index > 0 && rawPlaceholder.length() > index) { - suffix = rawPlaceholder.substring(index+1); - } - } - if (QuotedString.endsWithQuote(rawPlaceholder)) { - rawPlaceholder = rawPlaceholder.substring(0, rawPlaceholder.length() - (StringUtils.hasText(suffix) ? suffix.length() : 1)); + rawPlaceholder = matcher.group(); + if (rawPlaceholder.matches(".*\\d$")) { + suffix = ""; + } else { + int index = rawPlaceholder.replaceAll("[^\\?0-9]*$", "").length() - 1; + if (index > 0 && rawPlaceholder.length() > index) { + suffix = rawPlaceholder.substring(index + 1); } } - - if (StringUtils.hasText(suffix)) { - - boolean quoted = QuotedString.endsWithQuote(suffix); - - return Placeholder.of(parameterIndex, rawPlaceholder, quoted, - quoted ? QuotedString.unquoteSuffix(suffix) : suffix); + if (QuotedString.endsWithQuote(rawPlaceholder)) { + rawPlaceholder = rawPlaceholder.substring(0, + rawPlaceholder.length() - (StringUtils.hasText(suffix) ? suffix.length() : 1)); } - return Placeholder.of(parameterIndex, rawPlaceholder, false, null); } - return Placeholder.of(parameterIndex, matcher.group(), false, null); + if (StringUtils.hasText(suffix)) { + + boolean quoted = QuotedString.endsWithQuote(suffix); + + return Placeholder.of(parameterIndex, rawPlaceholder, quoted, + quoted ? QuotedString.unquoteSuffix(suffix) : suffix); + } + return Placeholder.of(parameterIndex, rawPlaceholder, false, null); } /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java index 9fb3dd782..2ea13d1a0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2016 the original author or authors. + * Copyright 2011-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,7 @@ import com.mongodb.util.JSON; /** * Query to use a plain JSON String to create the {@link Query} to actually execute. - * + * * @author Oliver Gierke * @author Christoph Strobl * @author Thomas Darimont @@ -61,7 +61,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery { /** * Creates a new {@link StringBasedMongoQuery} for the given {@link MongoQueryMethod} and {@link MongoOperations}. - * + * * @param method must not be {@literal null}. * @param mongoOperations must not be {@literal null}. * @param expressionParser must not be {@literal null}. @@ -99,7 +99,6 @@ public class StringBasedMongoQuery extends AbstractMongoQuery { this.parameterBinder = new ExpressionEvaluatingParameterBinder(expressionParser, evaluationContextProvider); - if (method.hasAnnotatedQuery()) { org.springframework.data.mongodb.repository.Query queryAnnotation = method.getQueryAnnotation(); @@ -127,10 +126,10 @@ public class StringBasedMongoQuery extends AbstractMongoQuery { @Override protected Query createQuery(ConvertingParameterAccessor accessor) { - String queryString = parameterBinder.bind(this.query, accessor, new BindingContext(getQueryMethod() - .getParameters(), queryParameterBindings)); - String fieldsString = parameterBinder.bind(this.fieldSpec, accessor, new BindingContext(getQueryMethod() - .getParameters(), fieldSpecParameterBindings)); + String queryString = parameterBinder.bind(this.query, accessor, + new BindingContext(getQueryMethod().getParameters(), queryParameterBindings)); + String fieldsString = parameterBinder.bind(this.fieldSpec, accessor, + new BindingContext(getQueryMethod().getParameters(), fieldSpecParameterBindings)); Query query = new BasicQuery(queryString, fieldsString).with(accessor.getSort()); @@ -141,7 +140,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery { return query; } - /* + /* * (non-Javadoc) * @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery#isCountQuery() */ @@ -168,7 +167,8 @@ public class StringBasedMongoQuery extends AbstractMongoQuery { return this.isDeleteQuery; } - private static boolean hasAmbiguousProjectionFlags(boolean isCountQuery, boolean isExistsQuery, boolean isDeleteQuery) { + private static boolean hasAmbiguousProjectionFlags(boolean isCountQuery, boolean isExistsQuery, + boolean isDeleteQuery) { return countBooleanValues(isCountQuery, isExistsQuery, isDeleteQuery) > 1; } @@ -188,7 +188,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery { /** * A parser that extracts the parameter bindings from a given query string. - * + * * @author Thomas Darimont */ private enum ParameterBindingParser { @@ -211,7 +211,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery { /** * Returns a list of {@link ParameterBinding}s found in the given {@code input} or an * {@link Collections#emptyList()}. - * + * * @param input can be {@literal null} or empty. * @param bindings must not be {@literal null}. * @return @@ -306,7 +306,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery { int paramIndex = Integer.parseInt(valueMatcher.group(PARAMETER_INDEX_GROUP)); /* - * The pattern is used as a direct parameter replacement, e.g. 'field': ?1, + * The pattern is used as a direct parameter replacement, e.g. 'field': ?1, * therefore we treat it as not quoted to remain backwards compatible. */ boolean quoted = !string.equals(PARAMETER_PREFIX + paramIndex); @@ -356,7 +356,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery { /** * A generic parameter binding with name or position information. - * + * * @author Thomas Darimont */ static class ParameterBinding { @@ -367,7 +367,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery { /** * Creates a new {@link ParameterBinding} with the given {@code parameterIndex} and {@code quoted} information. - * + * * @param parameterIndex * @param quoted whether or not the parameter is already quoted. */ diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQueryUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQueryUnitTests.java index eae807066..919c58475 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQueryUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQueryUnitTests.java @@ -60,7 +60,7 @@ import com.mongodb.util.JSON; /** * Unit tests for {@link StringBasedMongoQuery}. - * + * * @author Oliver Gierke * @author Christoph Strobl * @author Thomas Darimont