30
30
import org .springframework .data .mongodb .repository .query .MongoParameters .MongoParameter ;
31
31
import org .springframework .data .repository .query .Parameter ;
32
32
import org .springframework .data .repository .query .Parameters ;
33
+ import org .springframework .data .repository .query .ParametersSource ;
33
34
import org .springframework .data .util .TypeInformation ;
34
35
import org .springframework .lang .Nullable ;
35
36
@@ -49,38 +50,48 @@ public class MongoParameters extends Parameters<MongoParameters, MongoParameter>
49
50
private final @ Nullable Integer nearIndex ;
50
51
private final @ Nullable Integer collationIndex ;
51
52
private final int updateIndex ;
53
+ private final TypeInformation <?> domainType ;
52
54
53
55
/**
54
56
* Creates a new {@link MongoParameters} instance from the given {@link Method} and {@link MongoQueryMethod}.
55
57
*
56
- * @param method must not be {@literal null}.
58
+ * @param parametersSource must not be {@literal null}.
57
59
* @param isGeoNearMethod indicate if this is a geo spatial query method
58
60
*/
59
- public MongoParameters (Method method , boolean isGeoNearMethod ) {
61
+ public MongoParameters (ParametersSource parametersSource , boolean isGeoNearMethod ) {
62
+ this (parametersSource , new NearIndex (parametersSource , isGeoNearMethod ));
63
+ }
64
+
65
+ /**
66
+ * Creates a new {@link MongoParameters} instance from the given {@link Method} and {@link MongoQueryMethod}.
67
+ *
68
+ * @param parametersSource must not be {@literal null}.
69
+ * @param nearIndex the near parameter index.
70
+ */
71
+ private MongoParameters (ParametersSource parametersSource , NearIndex nearIndex ) {
60
72
61
- super (method );
73
+ super (parametersSource , methodParameter -> new MongoParameter (methodParameter ,
74
+ parametersSource .getDomainTypeInformation (), nearIndex .nearIndex ));
75
+
76
+ Method method = parametersSource .getMethod ();
62
77
List <Class <?>> parameterTypes = Arrays .asList (method .getParameterTypes ());
63
78
79
+ this .domainType = parametersSource .getDomainTypeInformation ();
64
80
this .fullTextIndex = parameterTypes .indexOf (TextCriteria .class );
65
81
66
- TypeInformation <?> declaringClassInfo = TypeInformation .of (method . getDeclaringClass ());
82
+ TypeInformation <?> declaringClassInfo = TypeInformation .of (parametersSource . getContainingClass ());
67
83
List <TypeInformation <?>> parameterTypeInfo = declaringClassInfo .getParameterTypes (method );
68
84
69
85
this .rangeIndex = getTypeIndex (parameterTypeInfo , Range .class , Distance .class );
70
86
this .maxDistanceIndex = this .rangeIndex == -1 ? getTypeIndex (parameterTypeInfo , Distance .class , null ) : -1 ;
71
87
this .collationIndex = getTypeIndex (parameterTypeInfo , Collation .class , null );
72
88
this .updateIndex = QueryUtils .indexOfAssignableParameter (UpdateDefinition .class , parameterTypes );
73
-
74
- int index = findNearIndexInParameters (method );
75
- if (index == -1 && isGeoNearMethod ) {
76
- index = getNearIndex (parameterTypes );
77
- }
78
-
79
- this .nearIndex = index ;
89
+ this .nearIndex = nearIndex .nearIndex ;
80
90
}
81
91
82
92
private MongoParameters (List <MongoParameter > parameters , int maxDistanceIndex , @ Nullable Integer nearIndex ,
83
- @ Nullable Integer fullTextIndex , int rangeIndex , @ Nullable Integer collationIndex , int updateIndex ) {
93
+ @ Nullable Integer fullTextIndex , int rangeIndex , @ Nullable Integer collationIndex , int updateIndex ,
94
+ TypeInformation <?> domainType ) {
84
95
85
96
super (parameters );
86
97
@@ -90,9 +101,25 @@ private MongoParameters(List<MongoParameter> parameters, int maxDistanceIndex, @
90
101
this .rangeIndex = rangeIndex ;
91
102
this .collationIndex = collationIndex ;
92
103
this .updateIndex = updateIndex ;
104
+ this .domainType = domainType ;
93
105
}
94
106
95
- private int getNearIndex (List <Class <?>> parameterTypes ) {
107
+ static class NearIndex {
108
+
109
+ private final @ Nullable Integer nearIndex ;
110
+
111
+ public NearIndex (ParametersSource parametersSource , boolean isGeoNearMethod ) {
112
+
113
+ int index = findNearIndexInParameters (parametersSource .getMethod ());
114
+ if (index == -1 && isGeoNearMethod ) {
115
+ index = getNearIndex (Arrays .asList (parametersSource .getMethod ().getParameterTypes ()));
116
+ }
117
+
118
+ this .nearIndex = index ;
119
+ }
120
+ }
121
+
122
+ private static int getNearIndex (List <Class <?>> parameterTypes ) {
96
123
97
124
for (Class <?> reference : Arrays .asList (Point .class , double [].class )) {
98
125
@@ -112,15 +139,18 @@ private int getNearIndex(List<Class<?>> parameterTypes) {
112
139
return -1 ;
113
140
}
114
141
115
- private int findNearIndexInParameters (Method method ) {
142
+ static int findNearIndexInParameters (Method method ) {
116
143
117
144
int index = -1 ;
118
145
for (java .lang .reflect .Parameter p : method .getParameters ()) {
119
146
120
- MongoParameter param = createParameter (MethodParameter .forParameter (p ));
121
- if (param .isManuallyAnnotatedNearParameter ()) {
147
+ MethodParameter methodParameter = MethodParameter .forParameter (p );
148
+
149
+ if ((Point .class .isAssignableFrom (methodParameter .getParameterType ())
150
+ || methodParameter .getParameterType ().equals (double [].class ))
151
+ && methodParameter .hasParameterAnnotation (Near .class )) {
122
152
if (index == -1 ) {
123
- index = param . getIndex ();
153
+ index = methodParameter . getParameterIndex ();
124
154
} else {
125
155
throw new IllegalStateException (
126
156
String .format ("Found multiple @Near annotations ond method %s; Only one allowed" , method ));
@@ -131,11 +161,6 @@ private int findNearIndexInParameters(Method method) {
131
161
return index ;
132
162
}
133
163
134
- @ Override
135
- protected MongoParameter createParameter (MethodParameter parameter ) {
136
- return new MongoParameter (parameter );
137
- }
138
-
139
164
public int getDistanceRangeIndex () {
140
165
return -1 ;
141
166
}
@@ -197,6 +222,7 @@ public int getCollationParameterIndex() {
197
222
198
223
/**
199
224
* Returns the index of the {@link UpdateDefinition} parameter or -1 if not present.
225
+ *
200
226
* @return -1 if not present.
201
227
* @since 3.4
202
228
*/
@@ -207,7 +233,7 @@ public int getUpdateIndex() {
207
233
@ Override
208
234
protected MongoParameters createFrom (List <MongoParameter > parameters ) {
209
235
return new MongoParameters (parameters , this .maxDistanceIndex , this .nearIndex , this .fullTextIndex , this .rangeIndex ,
210
- this .collationIndex , this .updateIndex );
236
+ this .collationIndex , this .updateIndex , this . domainType );
211
237
}
212
238
213
239
private int getTypeIndex (List <TypeInformation <?>> parameterTypes , Class <?> type , @ Nullable Class <?> componentType ) {
@@ -234,18 +260,21 @@ private int getTypeIndex(List<TypeInformation<?>> parameterTypes, Class<?> type,
234
260
*
235
261
* @author Oliver Gierke
236
262
*/
237
- class MongoParameter extends Parameter {
263
+ static class MongoParameter extends Parameter {
238
264
239
265
private final MethodParameter parameter ;
266
+ private final @ Nullable Integer nearIndex ;
240
267
241
268
/**
242
269
* Creates a new {@link MongoParameter}.
243
270
*
244
271
* @param parameter must not be {@literal null}.
272
+ * @param domainType must not be {@literal null}.
245
273
*/
246
- MongoParameter (MethodParameter parameter ) {
247
- super (parameter );
274
+ MongoParameter (MethodParameter parameter , TypeInformation <?> domainType , @ Nullable Integer nearIndex ) {
275
+ super (parameter , domainType );
248
276
this .parameter = parameter ;
277
+ this .nearIndex = nearIndex ;
249
278
250
279
if (!isPoint () && hasNearAnnotation ()) {
251
280
throw new IllegalArgumentException ("Near annotation is only allowed at Point parameter" );
@@ -259,7 +288,6 @@ public boolean isSpecialParameter() {
259
288
}
260
289
261
290
private boolean isNearParameter () {
262
- Integer nearIndex = MongoParameters .this .nearIndex ;
263
291
return nearIndex != null && nearIndex .equals (getIndex ());
264
292
}
265
293
0 commit comments