MongoParametersParameterAccessor.java
/*
* Copyright 2011-present 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.
* You may obtain a copy of the License at
*
* https://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.springframework.data.mongodb.repository.query;
import org.jspecify.annotations.Nullable;
import org.springframework.data.domain.Range;
import org.springframework.data.domain.Range.Bound;
import org.springframework.data.domain.Score;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.query.Collation;
import org.springframework.data.mongodb.core.query.Term;
import org.springframework.data.mongodb.core.query.TextCriteria;
import org.springframework.data.mongodb.core.query.UpdateDefinition;
import org.springframework.data.repository.query.ParametersParameterAccessor;
import org.springframework.lang.Contract;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* Mongo-specific {@link ParametersParameterAccessor} to allow access to the {@link Distance} parameter.
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Thomas Darimont
* @author Mark Paluch
*/
public class MongoParametersParameterAccessor extends ParametersParameterAccessor implements MongoParameterAccessor {
final MongoParameters parameters;
/**
* Creates a new {@link MongoParametersParameterAccessor}.
*
* @param method must not be {@literal null}.
* @param values must not be {@literal null}.
*/
public MongoParametersParameterAccessor(MongoQueryMethod method, Object[] values) {
this(method.getParameters(), values);
}
/**
* Creates a new {@link MongoParametersParameterAccessor}.
*
* @param parameters must not be {@literal null}.
* @param values must not be {@literal null}.
* @since 5.0
*/
public MongoParametersParameterAccessor(MongoParameters parameters, Object[] values) {
super(parameters, values);
this.parameters = parameters;
}
@SuppressWarnings("NullAway")
@Override
public Range<Score> getScoreRange() {
if (parameters.hasScoreRangeParameter()) {
return getValue(parameters.getScoreRangeIndex());
}
Score score = getScore();
Bound<Score> maxDistance = score != null ? Bound.inclusive(score) : Bound.unbounded();
return Range.of(Bound.unbounded(), maxDistance);
}
@SuppressWarnings("NullAway")
@Override
public Range<Distance> getDistanceRange() {
MongoParameters mongoParameters = parameters;
int rangeIndex = mongoParameters.getRangeIndex();
if (rangeIndex != -1) {
return getValue(rangeIndex);
}
int maxDistanceIndex = mongoParameters.getMaxDistanceIndex();
Bound<Distance> maxDistance = maxDistanceIndex == -1 ? Bound.unbounded()
: Bound.inclusive((Distance) getValue(maxDistanceIndex));
return Range.of(Bound.unbounded(), maxDistance);
}
public @Nullable Point getGeoNearLocation() {
int nearIndex = parameters.getNearIndex();
if (nearIndex == -1) {
return null;
}
Object value = getValue(nearIndex);
if (value == null) {
return null;
}
if (value instanceof double[] typedValue) {
if (typedValue.length != 2) {
throw new IllegalArgumentException("The given double[] must have exactly 2 elements");
} else {
return new Point(typedValue[0], typedValue[1]);
}
}
return (Point) value;
}
@Override
public @Nullable TextCriteria getFullText() {
int index = parameters.getFullTextParameterIndex();
return index >= 0 ? potentiallyConvertFullText(getValue(index)) : null;
}
@Contract("null -> fail")
protected TextCriteria potentiallyConvertFullText(@Nullable Object fullText) {
Assert.notNull(fullText, "Fulltext parameter must not be 'null'.");
if (fullText instanceof String stringValue) {
return TextCriteria.forDefaultLanguage().matching(stringValue);
}
if (fullText instanceof Term term) {
return TextCriteria.forDefaultLanguage().matching(term);
}
if (fullText instanceof TextCriteria textCriteria) {
return textCriteria;
}
throw new IllegalArgumentException(
String.format("Expected full text parameter to be one of String, Term or TextCriteria but found %s.",
ClassUtils.getShortName(fullText.getClass())));
}
@Override
public @Nullable Collation getCollation() {
if (parameters.getCollationParameterIndex() == -1) {
return null;
}
return getValue(parameters.getCollationParameterIndex());
}
@Override
public Object @Nullable[] getValues() {
return super.getValues();
}
@Override
public @Nullable UpdateDefinition getUpdate() {
int updateIndex = parameters.getUpdateIndex();
return updateIndex == -1 ? null : (UpdateDefinition) getValue(updateIndex);
}
}