@@ -95,6 +95,19 @@ public void setQualifierDelimiter(String qualifierDelimiter) {
95
95
this .qualifierDelimiter = qualifierDelimiter == null ? DEFAULT_QUALIFIER_DELIMITER : qualifierDelimiter ;
96
96
}
97
97
98
+ /**
99
+ * Configures the {@link Sort} to be used as fallback in case no {@link SortDefault} or {@link SortDefaults} (the
100
+ * latter only supported in legacy mode) can be found at the method parameter to be resolved.
101
+ * <p>
102
+ * If you set this to {@literal null}, be aware that you controller methods will get {@literal null} handed into them
103
+ * in case no {@link Sort} data can be found in the request.
104
+ *
105
+ * @param fallbackSort the {@link Sort} to be used as general fallback.
106
+ */
107
+ public void setFallbackSort (Sort fallbackSort ) {
108
+ this .fallbackSort = fallbackSort ;
109
+ }
110
+
98
111
/*
99
112
* (non-Javadoc)
100
113
* @see org.springframework.web.method.support.HandlerMethodArgumentResolver#supportsParameter(org.springframework.core.MethodParameter)
@@ -128,79 +141,81 @@ public Sort resolveArgument(MethodParameter parameter, @Nullable ModelAndViewCon
128
141
}
129
142
130
143
/**
131
- * Reads the default {@link Sort} to be used from the given {@link MethodParameter}. Rejects the parameter if both an
132
- * {@link SortDefaults} and {@link SortDefault} annotation is found as we cannot build a reliable {@link Sort}
133
- * instance then (property ordering).
144
+ * Returns the sort parameter to be looked up from the request. Potentially applies qualifiers to it.
134
145
*
135
- * @param parameter will never be {@literal null}.
136
- * @return the default {@link Sort} instance derived from the parameter annotations or the configured fallback-sort
137
- * {@link #setFallbackSort(Sort)}.
146
+ * @param parameter can be {@literal null}.
147
+ * @return
138
148
*/
139
- private Sort getDefaultFromAnnotationOrFallback (MethodParameter parameter ) {
140
-
141
- SortDefaults annotatedDefaults = parameter .getParameterAnnotation (SortDefaults .class );
142
- SortDefault annotatedDefault = parameter .getParameterAnnotation (SortDefault .class );
143
-
144
- if (annotatedDefault != null && annotatedDefaults != null ) {
145
- throw new IllegalArgumentException (
146
- String .format ("Cannot use both @%s and @%s on parameter %s! Move %s into %s to define sorting order!" ,
147
- SORT_DEFAULTS_NAME , SORT_DEFAULT_NAME , parameter .toString (), SORT_DEFAULT_NAME , SORT_DEFAULTS_NAME ));
148
- }
149
-
150
- if (annotatedDefault != null ) {
151
- return appendOrCreateSortTo (annotatedDefault , Sort .unsorted ());
152
- }
153
-
154
- if (annotatedDefaults != null ) {
149
+ protected String getSortParameter (@ Nullable MethodParameter parameter ) {
155
150
156
- Sort sort = Sort . unsorted ();
151
+ StringBuilder builder = new StringBuilder ();
157
152
158
- for (SortDefault currentAnnotatedDefault : annotatedDefaults .value ()) {
159
- sort = appendOrCreateSortTo (currentAnnotatedDefault , sort );
160
- }
153
+ Qualifier qualifier = parameter != null ? parameter .getParameterAnnotation (Qualifier .class ) : null ;
161
154
162
- return sort ;
155
+ if (qualifier != null ) {
156
+ builder .append (qualifier .value ()).append (qualifierDelimiter );
163
157
}
164
158
165
- return fallbackSort ;
159
+ return builder . append ( sortParameter ). toString () ;
166
160
}
167
161
168
162
/**
169
- * Creates a new {@link Sort} instance from the given {@link SortDefault} or appends it to the given {@link Sort}
170
- * instance if it's not {@literal null} .
163
+ * Folds the given {@link Sort} instance into a {@link List} of sort expressions, accumulating {@link Order} instances
164
+ * of the same direction into a single expression if they are in order .
171
165
*
172
- * @param sortDefault
173
- * @param sortOrNull
166
+ * @param sort must not be {@literal null}.
174
167
* @return
175
168
*/
176
- private Sort appendOrCreateSortTo ( SortDefault sortDefault , Sort sortOrNull ) {
169
+ protected List < String > foldIntoExpressions ( Sort sort ) {
177
170
178
- String [] fields = SpringDataAnnotationUtils .getSpecificPropertyOrDefaultFromValue (sortDefault , "sort" );
171
+ List <String > expressions = new ArrayList <>();
172
+ ExpressionBuilder builder = null ;
173
+
174
+ for (Order order : sort ) {
179
175
180
- if (fields .length == 0 ) {
181
- return Sort .unsorted ();
176
+ Direction direction = order .getDirection ();
177
+
178
+ if (builder == null ) {
179
+ builder = new ExpressionBuilder (direction );
180
+ } else if (!builder .hasSameDirectionAs (order )) {
181
+ builder .dumpExpressionIfPresentInto (expressions );
182
+ builder = new ExpressionBuilder (direction );
183
+ }
184
+
185
+ builder .add (order .getProperty ());
182
186
}
183
187
184
- return sortOrNull . and ( Sort . by ( sortDefault . direction (), fields ) );
188
+ return builder == null ? Collections . emptyList () : builder . dumpExpressionIfPresentInto ( expressions );
185
189
}
186
190
187
191
/**
188
- * Returns the sort parameter to be looked up from the request. Potentially applies qualifiers to it.
192
+ * Folds the given {@link Sort} instance into two expressions. The first being the property list, the second being the
193
+ * direction.
189
194
*
190
- * @param parameter can be {@literal null}.
195
+ * @throws IllegalArgumentException if a {@link Sort} with multiple {@link Direction}s has been handed in.
196
+ * @param sort must not be {@literal null}.
191
197
* @return
192
198
*/
193
- protected String getSortParameter ( @ Nullable MethodParameter parameter ) {
199
+ protected List < String > legacyFoldExpressions ( Sort sort ) {
194
200
195
- StringBuilder builder = new StringBuilder ();
201
+ List <String > expressions = new ArrayList <>();
202
+ ExpressionBuilder builder = null ;
196
203
197
- Qualifier qualifier = parameter != null ? parameter . getParameterAnnotation ( Qualifier . class ) : null ;
204
+ for ( Order order : sort ) {
198
205
199
- if (qualifier != null ) {
200
- builder .append (qualifier .value ()).append (qualifierDelimiter );
206
+ Direction direction = order .getDirection ();
207
+
208
+ if (builder == null ) {
209
+ builder = new ExpressionBuilder (direction );
210
+ } else if (!builder .hasSameDirectionAs (order )) {
211
+ throw new IllegalArgumentException (String .format (
212
+ "%s in legacy configuration only supports a single direction to sort by!" , getClass ().getSimpleName ()));
213
+ }
214
+
215
+ builder .add (order .getProperty ());
201
216
}
202
217
203
- return builder . append ( sortParameter ). toString ( );
218
+ return builder == null ? Collections . emptyList () : builder . dumpExpressionIfPresentInto ( expressions );
204
219
}
205
220
206
221
/**
@@ -226,10 +241,12 @@ Sort parseParameterIntoSort(String[] source, String delimiter) {
226
241
.filter (SortHandlerMethodArgumentResolver ::notOnlyDots ) //
227
242
.toArray (String []::new );
228
243
229
- Optional <Direction > direction = elements .length == 0 ? Optional .empty ()
244
+ Optional <Direction > direction = elements .length == 0 //
245
+ ? Optional .empty () //
230
246
: Direction .fromOptionalString (elements [elements .length - 1 ]);
231
247
232
- int lastIndex = direction .map (it -> elements .length - 1 ).orElseGet (() -> elements .length );
248
+ int lastIndex = direction .map (it -> elements .length - 1 ) //
249
+ .orElseGet (() -> elements .length );
233
250
234
251
for (int i = 0 ; i < lastIndex ; i ++) {
235
252
toOrder (elements [i ], direction ).ifPresent (allOrders ::add );
@@ -240,81 +257,76 @@ Sort parseParameterIntoSort(String[] source, String delimiter) {
240
257
}
241
258
242
259
/**
243
- * Returns whether the given source {@link String} consists of dots only.
260
+ * Reads the default {@link Sort} to be used from the given {@link MethodParameter}. Rejects the parameter if both an
261
+ * {@link SortDefaults} and {@link SortDefault} annotation is found as we cannot build a reliable {@link Sort}
262
+ * instance then (property ordering).
244
263
*
245
- * @param source must not be {@literal null}.
246
- * @return
264
+ * @param parameter will never be {@literal null}.
265
+ * @return the default {@link Sort} instance derived from the parameter annotations or the configured fallback-sort
266
+ * {@link #setFallbackSort(Sort)}.
247
267
*/
248
- private static boolean notOnlyDots (String source ) {
249
- return StringUtils .hasText (source .replace ("." , "" ));
250
- }
268
+ private Sort getDefaultFromAnnotationOrFallback (MethodParameter parameter ) {
251
269
252
- private static Optional <Order > toOrder (String property , Optional <Direction > direction ) {
270
+ SortDefaults annotatedDefaults = parameter .getParameterAnnotation (SortDefaults .class );
271
+ SortDefault annotatedDefault = parameter .getParameterAnnotation (SortDefault .class );
253
272
254
- if (!StringUtils .hasText (property )) {
255
- return Optional .empty ();
273
+ if (annotatedDefault != null && annotatedDefaults != null ) {
274
+ throw new IllegalArgumentException (
275
+ String .format ("Cannot use both @%s and @%s on parameter %s! Move %s into %s to define sorting order!" ,
276
+ SORT_DEFAULTS_NAME , SORT_DEFAULT_NAME , parameter .toString (), SORT_DEFAULT_NAME , SORT_DEFAULTS_NAME ));
256
277
}
257
278
258
- return Optional .of (direction .map (it -> new Order (it , property )).orElseGet (() -> Order .by (property )));
259
- }
260
-
261
- /**
262
- * Folds the given {@link Sort} instance into a {@link List} of sort expressions, accumulating {@link Order} instances
263
- * of the same direction into a single expression if they are in order.
264
- *
265
- * @param sort must not be {@literal null}.
266
- * @return
267
- */
268
- protected List <String > foldIntoExpressions (Sort sort ) {
269
-
270
- List <String > expressions = new ArrayList <>();
271
- ExpressionBuilder builder = null ;
279
+ if (annotatedDefault != null ) {
280
+ return appendOrCreateSortTo (annotatedDefault , Sort .unsorted ());
281
+ }
272
282
273
- for ( Order order : sort ) {
283
+ if ( annotatedDefaults != null ) {
274
284
275
- Direction direction = order . getDirection ();
285
+ Sort sort = Sort . unsorted ();
276
286
277
- if (builder == null ) {
278
- builder = new ExpressionBuilder (direction );
279
- } else if (!builder .hasSameDirectionAs (order )) {
280
- builder .dumpExpressionIfPresentInto (expressions );
281
- builder = new ExpressionBuilder (direction );
287
+ for (SortDefault currentAnnotatedDefault : annotatedDefaults .value ()) {
288
+ sort = appendOrCreateSortTo (currentAnnotatedDefault , sort );
282
289
}
283
290
284
- builder . add ( order . getProperty ()) ;
291
+ return sort ;
285
292
}
286
293
287
- return builder == null ? Collections . emptyList () : builder . dumpExpressionIfPresentInto ( expressions ) ;
294
+ return fallbackSort ;
288
295
}
289
296
290
297
/**
291
- * Folds the given {@link Sort} instance into two expressions. The first being the property list, the second being the
292
- * direction .
298
+ * Creates a new {@link Sort} instance from the given {@link SortDefault} or appends it to the given {@link Sort}
299
+ * instance if it's not {@literal null} .
293
300
*
294
- * @throws IllegalArgumentException if a {@link Sort} with multiple {@link Direction}s has been handed in.
295
- * @param sort must not be {@literal null}.
301
+ * @param sortDefault
302
+ * @param sortOrNull
296
303
* @return
297
304
*/
298
- protected List <String > legacyFoldExpressions (Sort sort ) {
299
-
300
- List <String > expressions = new ArrayList <>();
301
- ExpressionBuilder builder = null ;
305
+ private Sort appendOrCreateSortTo (SortDefault sortDefault , Sort sortOrNull ) {
302
306
303
- for ( Order order : sort ) {
307
+ String [] fields = SpringDataAnnotationUtils . getSpecificPropertyOrDefaultFromValue ( sortDefault , " sort" );
304
308
305
- Direction direction = order .getDirection ();
309
+ return fields .length == 0 //
310
+ ? Sort .unsorted ()
311
+ : sortOrNull .and (Sort .by (sortDefault .direction (), fields ));
312
+ }
306
313
307
- if (builder == null ) {
308
- builder = new ExpressionBuilder (direction );
309
- } else if (!builder .hasSameDirectionAs (order )) {
310
- throw new IllegalArgumentException (String .format (
311
- "%s in legacy configuration only supports a single direction to sort by!" , getClass ().getSimpleName ()));
312
- }
314
+ /**
315
+ * Returns whether the given source {@link String} consists of dots only.
316
+ *
317
+ * @param source must not be {@literal null}.
318
+ * @return
319
+ */
320
+ private static boolean notOnlyDots (String source ) {
321
+ return StringUtils .hasText (source .replace ("." , "" ));
322
+ }
313
323
314
- builder .add (order .getProperty ());
315
- }
324
+ private static Optional <Order > toOrder (String property , Optional <Direction > direction ) {
316
325
317
- return builder == null ? Collections .emptyList () : builder .dumpExpressionIfPresentInto (expressions );
326
+ return !StringUtils .hasText (property ) //
327
+ ? Optional .empty () //
328
+ : Optional .of (direction .map (it -> new Order (it , property )) //
329
+ .orElseGet (() -> Order .by (property )));
318
330
}
319
331
320
332
/**
@@ -376,17 +388,4 @@ public List<String> dumpExpressionIfPresentInto(List<String> expressions) {
376
388
return expressions ;
377
389
}
378
390
}
379
-
380
- /**
381
- * Configures the {@link Sort} to be used as fallback in case no {@link SortDefault} or {@link SortDefaults} (the
382
- * latter only supported in legacy mode) can be found at the method parameter to be resolved.
383
- * <p>
384
- * If you set this to {@literal null}, be aware that you controller methods will get {@literal null} handed into them
385
- * in case no {@link Sort} data can be found in the request.
386
- *
387
- * @param fallbackSort the {@link Sort} to be used as general fallback.
388
- */
389
- public void setFallbackSort (Sort fallbackSort ) {
390
- this .fallbackSort = fallbackSort ;
391
- }
392
391
}
0 commit comments