From a63a2bbd756c5c74a9e680948b91f8109cbbef91 Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Wed, 7 Aug 2013 12:10:43 +0200 Subject: [PATCH] =?UTF-8?q?DATACMNS-351=20-=20Add=20setFallbackSort(?= =?UTF-8?q?=E2=80=A6)=20to=20SortHandlerMethodArgumentResolver.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SortHandlerMethodArgumentResolver now has a setFallbackSort(…) to be able to configure the Sort instance to be used if nothing can be resolved from the request and sort default is configured on the controller method. Renamed name of getDefaults(…) method in SortHandlerMethodArgumentResolver to getDefaultFromAnnotationOrFallback(…) and refactored implementation to be more understandable. Original pull request: #36 --- .../SortHandlerMethodArgumentResolver.java | 51 ++++++++++++------- .../SortHandlerArgumentResolverUnitTests.java | 29 +++++++++++ 2 files changed, 63 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/springframework/data/web/SortHandlerMethodArgumentResolver.java b/src/main/java/org/springframework/data/web/SortHandlerMethodArgumentResolver.java index b0534f988..5289da0b0 100644 --- a/src/main/java/org/springframework/data/web/SortHandlerMethodArgumentResolver.java +++ b/src/main/java/org/springframework/data/web/SortHandlerMethodArgumentResolver.java @@ -41,16 +41,19 @@ import org.springframework.web.util.UriComponentsBuilder; * * @since 1.6 * @author Oliver Gierke + * @author Thomas Darimont */ public class SortHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver, UriComponentsContributor { private static final String DEFAULT_PARAMETER = "sort"; private static final String DEFAULT_PROPERTY_DELIMITER = ","; private static final String DEFAULT_QUALIFIER_DELIMITER = "_"; + private static final Sort DEFAULT_SORT = null; private static final String SORT_DEFAULTS_NAME = SortDefaults.class.getSimpleName(); private static final String SORT_DEFAULT_NAME = SortDefault.class.getSimpleName(); + private Sort fallbackSort = DEFAULT_SORT; private String sortParameter = DEFAULT_PARAMETER; private String propertyDelimiter = DEFAULT_PROPERTY_DELIMITER; private String qualifierDelimiter = DEFAULT_QUALIFIER_DELIMITER; @@ -150,7 +153,7 @@ public class SortHandlerMethodArgumentResolver implements HandlerMethodArgumentR return legacyMode ? parseLegacyParameterIntoSort(webRequest, parameter) : parseParameterIntoSort( directionParameter, propertyDelimiter); } else { - return getDefaults(parameter); + return getDefaultFromAnnotationOrFallback(parameter); } } @@ -160,32 +163,33 @@ public class SortHandlerMethodArgumentResolver implements HandlerMethodArgumentR * instance then (property ordering). * * @param parameter will never be {@literal null}. - * @return the default {@link Sort} instance derived from the parameter annotations or {@literal null}. + * @return the default {@link Sort} instance derived from the parameter annotations or the configured fallback-sort + * {@link #setFallbackSort(Sort)}. */ - private Sort getDefaults(MethodParameter parameter) { + private Sort getDefaultFromAnnotationOrFallback(MethodParameter parameter) { SortDefaults annotatedDefaults = parameter.getParameterAnnotation(SortDefaults.class); - Sort sort = null; - - if (annotatedDefaults != null) { - for (SortDefault annotatedDefault : annotatedDefaults.value()) { - sort = appendOrCreateSortTo(annotatedDefault, sort); - } - } - SortDefault annotatedDefault = parameter.getParameterAnnotation(SortDefault.class); - if (annotatedDefault == null) { - return sort; - } - - if (sort != null && annotatedDefault != null) { + if (annotatedDefault != null && annotatedDefaults != null) { throw new IllegalArgumentException(String.format( "Cannot use both @%s and @%s on parameter %s! Move %s into %s to define sorting order!", SORT_DEFAULTS_NAME, SORT_DEFAULT_NAME, parameter.toString(), SORT_DEFAULT_NAME, SORT_DEFAULTS_NAME)); } - return appendOrCreateSortTo(annotatedDefault, sort); + if (annotatedDefault != null) { + return appendOrCreateSortTo(annotatedDefault, null); + } + + if (annotatedDefaults != null) { + Sort sort = null; + for (SortDefault currentAnnotatedDefault : annotatedDefaults.value()) { + sort = appendOrCreateSortTo(currentAnnotatedDefault, sort); + } + return sort; + } + + return fallbackSort; } /** @@ -404,4 +408,17 @@ public class SortHandlerMethodArgumentResolver implements HandlerMethodArgumentR return expressions; } } + + /** + * Configures the {@link Sort} to be used as fallback in case no {@link SortDefault} or {@link SortDefaults} (the + * latter only supported in legacy mode) can be found at the method parameter to be resolved. + *

+ * If you set this to {@literal null}, be aware that you controller methods will get {@literal null} handed into them + * in case no {@link Sort} data can be found in the request. + * + * @param fallbackSort the {@link Sort} to be used as general fallback. + */ + public void setFallbackSort(Sort fallbackSort) { + this.fallbackSort = fallbackSort; + } } diff --git a/src/test/java/org/springframework/data/web/SortHandlerArgumentResolverUnitTests.java b/src/test/java/org/springframework/data/web/SortHandlerArgumentResolverUnitTests.java index 72dc4d67b..df0fa39aa 100644 --- a/src/test/java/org/springframework/data/web/SortHandlerArgumentResolverUnitTests.java +++ b/src/test/java/org/springframework/data/web/SortHandlerArgumentResolverUnitTests.java @@ -37,6 +37,7 @@ import org.springframework.web.util.UriComponentsBuilder; * * @since 1.6 * @author Oliver Gierke + * @author Thomas Darimont */ public class SortHandlerArgumentResolverUnitTests extends SortDefaultUnitTests { @@ -45,6 +46,34 @@ public class SortHandlerArgumentResolverUnitTests extends SortDefaultUnitTests { static final String[] SORT_2 = new String[] { "username,ASC", "lastname,firstname,DESC" }; static final String SORT_3 = "firstname,lastname"; + /** + * @see DATACMNS-351 + */ + @Test + public void fallbackToGivenDefaultSort() throws Exception { + + MethodParameter parameter = TestUtils.getParameterOfMethod(getControllerClass(), "unsupportedMethod", String.class); + SortHandlerMethodArgumentResolver resolver = new SortHandlerMethodArgumentResolver(); + Sort fallbackSort = new Sort(Direction.ASC, "ID"); + resolver.setFallbackSort(fallbackSort); + + Sort sort = resolver.resolveArgument(parameter, null, new ServletWebRequest(new MockHttpServletRequest()), null); + assertThat(sort, is(fallbackSort)); + } + + /** + * @see DATACMNS-351 + */ + @Test + public void fallbackToDefaultDefaultSort() throws Exception { + + MethodParameter parameter = TestUtils.getParameterOfMethod(getControllerClass(), "unsupportedMethod", String.class); + SortHandlerMethodArgumentResolver resolver = new SortHandlerMethodArgumentResolver(); + + Sort sort = resolver.resolveArgument(parameter, null, new ServletWebRequest(new MockHttpServletRequest()), null); + assertThat(sort, is(nullValue())); + } + @Test public void discoversSimpleSortFromRequest() {