Skip to content

Commit 2c27e85

Browse files
committed
DATAMONGO-990 - Polishing.
Removed EvaluationExpressionContext from all AbstractMongoQuery implementations that don't actually need it and from AbstractMongoQuery itself, too. Cleaned up test cases after that. Moved SpEL related tests into AbstractPersonRepositoryIntegrationTests to make sure they're executed for all sub-types. JavaDoc and assertion polishes. Original pull request: spring-projects#285.
1 parent 67f638d commit 2c27e85

14 files changed

+166
-189
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import org.springframework.data.mongodb.core.MongoOperations;
3232
import org.springframework.data.mongodb.core.query.NearQuery;
3333
import org.springframework.data.mongodb.core.query.Query;
34-
import org.springframework.data.repository.query.EvaluationContextProvider;
3534
import org.springframework.data.repository.query.ParameterAccessor;
3635
import org.springframework.data.repository.query.RepositoryQuery;
3736
import org.springframework.data.util.CloseableIterator;
@@ -52,25 +51,20 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
5251

5352
private final MongoQueryMethod method;
5453
private final MongoOperations operations;
55-
private final EvaluationContextProvider evaluationContextProvider;
5654

5755
/**
5856
* Creates a new {@link AbstractMongoQuery} from the given {@link MongoQueryMethod} and {@link MongoOperations}.
5957
*
6058
* @param method must not be {@literal null}.
6159
* @param operations must not be {@literal null}.
62-
* @param evaluationContextProvider must not be {@literal null}.
6360
*/
64-
public AbstractMongoQuery(MongoQueryMethod method, MongoOperations operations,
65-
EvaluationContextProvider evaluationContextProvider) {
61+
public AbstractMongoQuery(MongoQueryMethod method, MongoOperations operations) {
6662

67-
Assert.notNull(operations);
68-
Assert.notNull(method);
69-
Assert.notNull(evaluationContextProvider, "ExpressionEvaluationContextProvider must not be null!");
63+
Assert.notNull(operations, "MongoOperations must not be null!");
64+
Assert.notNull(method, "MongoQueryMethod must not be null!");
7065

7166
this.method = method;
7267
this.operations = operations;
73-
this.evaluationContextProvider = evaluationContextProvider;
7468
}
7569

7670
/*
@@ -164,10 +158,6 @@ protected Query createCountQuery(ConvertingParameterAccessor accessor) {
164158
*/
165159
protected abstract boolean isDeleteQuery();
166160

167-
public EvaluationContextProvider getEvaluationContextProvider() {
168-
return evaluationContextProvider;
169-
}
170-
171161
private abstract class Execution {
172162

173163
abstract Object execute(Query query);
@@ -318,8 +308,8 @@ private SingleEntityExecution(boolean countProjection) {
318308
Object execute(Query query) {
319309

320310
MongoEntityMetadata<?> metadata = method.getEntityInformation();
321-
return countProjection ? operations.count(query, metadata.getJavaType()) : operations.findOne(query,
322-
metadata.getJavaType(), metadata.getCollectionName());
311+
return countProjection ? operations.count(query, metadata.getJavaType())
312+
: operations.findOne(query, metadata.getJavaType(), metadata.getCollectionName());
323313
}
324314
}
325315

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ public void remove() {
217217
/**
218218
* Returns the given object as {@link Collection}. Will do a copy of it if it implements {@link Iterable} or is an
219219
* array. Will return an empty {@link Collection} in case {@literal null} is given. Will wrap all other types into a
220-
* single-element collction
220+
* single-element collection.
221221
*
222222
* @param source
223223
* @return
@@ -240,8 +240,9 @@ private static Collection<?> asCollection(Object source) {
240240

241241
return source.getClass().isArray() ? CollectionUtils.arrayToList(source) : Collections.singleton(source);
242242
}
243-
244-
/* (non-Javadoc)
243+
244+
/*
245+
* (non-Javadoc)
245246
* @see org.springframework.data.mongodb.repository.query.MongoParameterAccessor#getValues()
246247
*/
247248
@Override

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParametersParameterAccessor.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,13 @@ protected TextCriteria potentiallyConvertFullText(Object fullText) {
120120
return ((TextCriteria) fullText);
121121
}
122122

123-
throw new IllegalArgumentException(String.format(
124-
"Expected full text parameter to be one of String, Term or TextCriteria but found %s.",
125-
ClassUtils.getShortName(fullText.getClass())));
123+
throw new IllegalArgumentException(
124+
String.format("Expected full text parameter to be one of String, Term or TextCriteria but found %s.",
125+
ClassUtils.getShortName(fullText.getClass())));
126126
}
127-
128-
/* (non-Javadoc)
127+
128+
/*
129+
* (non-Javadoc)
129130
* @see org.springframework.data.mongodb.repository.query.MongoParameterAccessor#getValues()
130131
*/
131132
@Override

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/PartTreeMongoQuery.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import org.springframework.data.mongodb.core.query.BasicQuery;
2323
import org.springframework.data.mongodb.core.query.Query;
2424
import org.springframework.data.mongodb.core.query.TextCriteria;
25-
import org.springframework.data.repository.query.EvaluationContextProvider;
2625
import org.springframework.data.repository.query.QueryMethod;
2726
import org.springframework.data.repository.query.RepositoryQuery;
2827
import org.springframework.data.repository.query.parser.PartTree;
@@ -48,12 +47,10 @@ public class PartTreeMongoQuery extends AbstractMongoQuery {
4847
*
4948
* @param method must not be {@literal null}.
5049
* @param mongoOperations must not be {@literal null}.
51-
* @param evaluationContextProvider must not be {@literal null}.
5250
*/
53-
public PartTreeMongoQuery(MongoQueryMethod method, MongoOperations mongoOperations,
54-
EvaluationContextProvider evaluationContextProvider) {
51+
public PartTreeMongoQuery(MongoQueryMethod method, MongoOperations mongoOperations) {
5552

56-
super(method, mongoOperations, evaluationContextProvider);
53+
super(method, mongoOperations);
5754
this.tree = new PartTree(method.getName(), method.getEntityInformation().getJavaType());
5855
this.isGeoNearQuery = method.isGeoNearQuery();
5956
this.context = mongoOperations.getConverter().getMappingContext();

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQuery.java

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -57,36 +57,40 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
5757
private final List<ParameterBinding> queryParameterBindings;
5858
private final List<ParameterBinding> fieldSpecParameterBindings;
5959
private final SpelExpressionParser expressionParser;
60+
private final EvaluationContextProvider evaluationContextProvider;
6061

6162
/**
6263
* Creates a new {@link StringBasedMongoQuery} for the given {@link MongoQueryMethod} and {@link MongoOperations}.
6364
*
6465
* @param method must not be {@literal null}.
6566
* @param mongoOperations must not be {@literal null}.
66-
* @param evaluationContextProvider must not be {@literal null}.
6767
* @param expressionParser must not be {@literal null}.
68+
* @param evaluationContextProvider must not be {@literal null}.
6869
*/
6970
public StringBasedMongoQuery(MongoQueryMethod method, MongoOperations mongoOperations,
70-
EvaluationContextProvider evaluationContextProvider, SpelExpressionParser expressionParser) {
71-
this(method.getAnnotatedQuery(), method, mongoOperations, evaluationContextProvider, expressionParser);
71+
SpelExpressionParser expressionParser, EvaluationContextProvider evaluationContextProvider) {
72+
this(method.getAnnotatedQuery(), method, mongoOperations, expressionParser, evaluationContextProvider);
7273
}
7374

7475
/**
75-
* Creates a new {@link StringBasedMongoQuery} for the given {@link String}, {@link MongoQueryMethod} and
76-
* {@link MongoOperations}.
77-
*
76+
* Creates a new {@link StringBasedMongoQuery} for the given {@link String}, {@link MongoQueryMethod},
77+
* {@link MongoOperations}, {@link SpelExpressionParser} and {@link EvaluationContextProvider}.
78+
*
79+
* @param query must not be {@literal null}.
7880
* @param method must not be {@literal null}.
81+
* @param mongoOperations must not be {@literal null}.
7982
* @param expressionParser must not be {@literal null}.
80-
* @param template must not be {@literal null}.
8183
*/
8284
public StringBasedMongoQuery(String query, MongoQueryMethod method, MongoOperations mongoOperations,
83-
EvaluationContextProvider evaluationContextProvider, SpelExpressionParser expressionParser) {
85+
SpelExpressionParser expressionParser, EvaluationContextProvider evaluationContextProvider) {
8486

85-
super(method, mongoOperations, evaluationContextProvider);
87+
super(method, mongoOperations);
8688

89+
Assert.notNull(query, "Query must not be null!");
8790
Assert.notNull(expressionParser, "SpelExpressionParser must not be null!");
8891

8992
this.expressionParser = expressionParser;
93+
this.evaluationContextProvider = evaluationContextProvider;
9094

9195
this.queryParameterBindings = new ArrayList<ParameterBinding>();
9296
this.query = BINDING_PARSER.parseAndCollectParameterBindingsFromQueryIntoBindings(query,
@@ -157,7 +161,8 @@ protected boolean isDeleteQuery() {
157161
* @param bindings
158162
* @return
159163
*/
160-
private String replacePlaceholders(String input, ConvertingParameterAccessor accessor, List<ParameterBinding> bindings) {
164+
private String replacePlaceholders(String input, ConvertingParameterAccessor accessor,
165+
List<ParameterBinding> bindings) {
161166

162167
if (bindings.isEmpty()) {
163168
return input;
@@ -187,12 +192,8 @@ private String replacePlaceholders(String input, ConvertingParameterAccessor acc
187192
*/
188193
private String getParameterValueForBinding(ConvertingParameterAccessor accessor, ParameterBinding binding) {
189194

190-
Object value = null;
191-
if (binding.isExpression()) {
192-
value = evaluateExpression(binding.getExpression(), accessor.getValues());
193-
} else {
194-
value = accessor.getBindableValue(binding.getParameterIndex());
195-
}
195+
Object value = binding.isExpression() ? evaluateExpression(binding.getExpression(), accessor.getValues())
196+
: accessor.getBindableValue(binding.getParameterIndex());
196197

197198
if (value instanceof String && binding.isQuoted()) {
198199
return (String) value;
@@ -210,8 +211,8 @@ private String getParameterValueForBinding(ConvertingParameterAccessor accessor,
210211
*/
211212
private Object evaluateExpression(String expressionString, Object[] parameterValues) {
212213

213-
EvaluationContext evaluationContext = getEvaluationContextProvider().getEvaluationContext(
214-
getQueryMethod().getParameters(), parameterValues);
214+
EvaluationContext evaluationContext = evaluationContextProvider
215+
.getEvaluationContext(getQueryMethod().getParameters(), parameterValues);
215216
Expression expression = expressionParser.parseExpression(expressionString);
216217
return expression.getValue(evaluationContext, Object.class);
217218
}
@@ -237,8 +238,8 @@ private static enum ParameterBindingParser {
237238
* Returns a list of {@link ParameterBinding}s found in the given {@code input} or an
238239
* {@link Collections#emptyList()}.
239240
*
240-
* @param input
241-
* @param bindings
241+
* @param input can be {@literal null} or empty.
242+
* @param bindings must not be {@literal null}.
242243
* @return
243244
*/
244245
public String parseAndCollectParameterBindingsFromQueryIntoBindings(String input, List<ParameterBinding> bindings) {
@@ -247,37 +248,36 @@ public String parseAndCollectParameterBindingsFromQueryIntoBindings(String input
247248
return input;
248249
}
249250

250-
String transformedInput = transformQueryAndCollectExpressionParametersIntoBindings(bindings, input);
251+
Assert.notNull(bindings, "Parameter bindings must not be null!");
251252

253+
String transformedInput = transformQueryAndCollectExpressionParametersIntoBindings(input, bindings);
252254
String parseableInput = makeParameterReferencesParseable(transformedInput);
253255

254256
collectParameterReferencesIntoBindings(bindings, JSON.parse(parseableInput));
255257

256258
return transformedInput;
257259
}
258260

259-
private String transformQueryAndCollectExpressionParametersIntoBindings(List<ParameterBinding> bindings,
260-
String input) {
261+
private String transformQueryAndCollectExpressionParametersIntoBindings(String input,
262+
List<ParameterBinding> bindings) {
261263

262264
Matcher matcher = PARAMETER_EXPRESSION_PATTERN.matcher(input);
263265

264266
StringBuilder result = new StringBuilder();
265267

266268
int lastPos = 0;
267-
268269
int exprIndex = 0;
270+
269271
while (matcher.find()) {
270272

271273
int startOffSet = matcher.start();
272-
result.append(input.subSequence(lastPos, startOffSet));
273-
274-
String expression = matcher.group(3);
275274

275+
result.append(input.subSequence(lastPos, startOffSet));
276276
result.append("'?expr").append(exprIndex).append("'");
277277

278278
lastPos = matcher.end();
279279

280-
bindings.add(new ParameterBinding(exprIndex, true, expression));
280+
bindings.add(new ParameterBinding(exprIndex, true, matcher.group(3)));
281281

282282
exprIndex++;
283283
}
@@ -305,9 +305,10 @@ private void collectParameterReferencesIntoBindings(List<ParameterBinding> bindi
305305
} else if (value instanceof Pattern) {
306306

307307
String string = ((Pattern) value).toString().trim();
308-
309308
Matcher valueMatcher = PARSEABLE_BINDING_PATTERN.matcher(string);
309+
310310
while (valueMatcher.find()) {
311+
311312
int paramIndex = Integer.parseInt(valueMatcher.group(PARAMETER_INDEX_GROUP));
312313

313314
/*

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactory.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
package org.springframework.data.mongodb.repository.support;
1717

18-
import static org.springframework.data.querydsl.QueryDslUtils.QUERY_DSL_PRESENT;
18+
import static org.springframework.data.querydsl.QueryDslUtils.*;
1919

2020
import java.io.Serializable;
2121
import java.lang.reflect.Method;
@@ -51,7 +51,7 @@
5151
public class MongoRepositoryFactory extends RepositoryFactorySupport {
5252

5353
private static final SpelExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();
54-
54+
5555
private final MongoOperations mongoOperations;
5656
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
5757

@@ -92,8 +92,8 @@ protected Object getTargetRepository(RepositoryInformation information) {
9292
return getTargetRepositoryViaReflection(information, entityInformation, mongoOperations);
9393
}
9494

95-
96-
/* (non-Javadoc)
95+
/*
96+
* (non-Javadoc)
9797
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key, org.springframework.data.repository.query.EvaluationContextProvider)
9898
*/
9999
@Override
@@ -112,8 +112,8 @@ public <T, ID extends Serializable> MongoEntityInformation<T, ID> getEntityInfor
112112
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(domainClass);
113113

114114
if (entity == null) {
115-
throw new MappingException(String.format("Could not lookup mapping metadata for domain class %s!",
116-
domainClass.getName()));
115+
throw new MappingException(
116+
String.format("Could not lookup mapping metadata for domain class %s!", domainClass.getName()));
117117
}
118118

119119
return new MappingMongoEntityInformation<T, ID>((MongoPersistentEntity<T>) entity);
@@ -144,11 +144,12 @@ public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata,
144144

145145
if (namedQueries.hasQuery(namedQueryName)) {
146146
String namedQuery = namedQueries.getQuery(namedQueryName);
147-
return new StringBasedMongoQuery(namedQuery, queryMethod, mongoOperations, evaluationContextProvider, EXPRESSION_PARSER);
147+
return new StringBasedMongoQuery(namedQuery, queryMethod, mongoOperations, EXPRESSION_PARSER,
148+
evaluationContextProvider);
148149
} else if (queryMethod.hasAnnotatedQuery()) {
149-
return new StringBasedMongoQuery(queryMethod, mongoOperations, evaluationContextProvider, EXPRESSION_PARSER);
150+
return new StringBasedMongoQuery(queryMethod, mongoOperations, EXPRESSION_PARSER, evaluationContextProvider);
150151
} else {
151-
return new PartTreeMongoQuery(queryMethod, mongoOperations, evaluationContextProvider);
152+
return new PartTreeMongoQuery(queryMethod, mongoOperations);
152153
}
153154
}
154155
}

0 commit comments

Comments
 (0)