Polishing.
Allow nullable OffsetScrollPosition and add support for values wrapped within Optional. Update tests. Reformat code. Add issue tags to tests. See #2856 Original pull request: #2861
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2023 the original author or authors.
|
||||
* Copyright 2023 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.
|
||||
@@ -17,7 +17,6 @@ package org.springframework.data.web;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.domain.OffsetScrollPosition;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
@@ -27,27 +26,31 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
/**
|
||||
* Argument resolver to extract a {@link OffsetScrollPosition} object from a {@link NativeWebRequest} for a particular
|
||||
* {@link MethodParameter}. A {@link OffsetScrollPositionArgumentResolver} can either resolve {@link OffsetScrollPosition} itself or wrap another
|
||||
* {@link OffsetScrollPositionArgumentResolver} to post-process {@link OffsetScrollPosition}.
|
||||
* {@link MethodParameter}. A {@link OffsetScrollPositionArgumentResolver} can either resolve
|
||||
* {@link OffsetScrollPosition} itself or wrap another {@link OffsetScrollPositionArgumentResolver} to post-process
|
||||
* {@link OffsetScrollPosition}.
|
||||
*
|
||||
* @since 3.2
|
||||
* @author Yanming Zhou
|
||||
* @see HandlerMethodArgumentResolver
|
||||
* @author Mark Paluch
|
||||
* @since 3.2
|
||||
* @see org.springframework.web.method.support.HandlerMethodArgumentResolver
|
||||
*/
|
||||
public interface OffsetScrollPositionArgumentResolver extends HandlerMethodArgumentResolver {
|
||||
|
||||
/**
|
||||
* Resolves a {@link OffsetScrollPosition} method parameter into an argument value from a given request.
|
||||
* Resolves a {@link OffsetScrollPosition} method parameter into an argument value from a given request. Supports also
|
||||
* wrapped arguments in {@link java.util.Optional}.
|
||||
*
|
||||
* @param parameter the method parameter to resolve. This parameter must have previously been passed to
|
||||
* {@link #supportsParameter} which must have returned {@code true}.
|
||||
* @param mavContainer the ModelAndViewContainer for the current request
|
||||
* @param webRequest the current request
|
||||
* @param binderFactory a factory for creating {@link WebDataBinder} instances
|
||||
* @return the resolved argument value
|
||||
* @return the resolved argument value or {@literal null} if the value cannot be resolved. The returned value
|
||||
* considers {@link MethodParameter#isOptional() Optional} wrapping by returing either the value wrapped
|
||||
* within Optional or Optional.empty().
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
OffsetScrollPosition resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
|
||||
Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
* Copyright 2023 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.
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.web;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.domain.OffsetScrollPosition;
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -23,27 +25,28 @@ import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* {@link HandlerMethodArgumentResolver} to automatically create {@link OffsetScrollPosition} instances from request parameters.
|
||||
* {@link HandlerMethodArgumentResolver} to automatically create {@link OffsetScrollPosition} instances from request
|
||||
* parameters.
|
||||
*
|
||||
* @since 3.2
|
||||
* @author Yanming Zhou
|
||||
* @since 3.2
|
||||
*/
|
||||
public class OffsetScrollPositionHandlerMethodArgumentResolver extends OffsetScrollPositionHandlerMethodArgumentResolverSupport
|
||||
implements OffsetScrollPositionArgumentResolver {
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(MethodParameter parameter) {
|
||||
return OffsetScrollPosition.class.equals(parameter.getParameterType());
|
||||
return OffsetScrollPosition.class.equals(parameter.nestedIfOptional().getNestedParameterType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public OffsetScrollPosition resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
|
||||
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) {
|
||||
|
||||
String[] offsetParameter = webRequest.getParameterValues(getOffsetParameter(parameter));
|
||||
return parseParameterIntoOffsetScrollPosition(offsetParameter != null ? Arrays.asList(offsetParameter) : null);
|
||||
String[] offsetParameter = webRequest.getParameterValues(getOffsetParameter(parameter.nestedIfOptional()));
|
||||
return adaptArgumentIfNecessary(
|
||||
parseParameterIntoOffsetScrollPosition(offsetParameter != null ? Arrays.asList(offsetParameter) : null),
|
||||
parameter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2023 the original author or authors.
|
||||
* Copyright 2023 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.
|
||||
@@ -15,22 +15,23 @@
|
||||
*/
|
||||
package org.springframework.data.web;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.domain.OffsetScrollPosition;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Base class providing methods for handler method argument resolvers to create {@link OffsetScrollPosition} instances from request
|
||||
* parameters.
|
||||
* Base class providing methods for handler method argument resolvers to create {@link OffsetScrollPosition} instances
|
||||
* from request parameters.
|
||||
*
|
||||
* @since 3.2
|
||||
* @author Yanming Zhou
|
||||
* @since 3.2
|
||||
* @see OffsetScrollPositionHandlerMethodArgumentResolver
|
||||
* @see ReactiveOffsetScrollPositionHandlerMethodArgumentResolver
|
||||
*/
|
||||
@@ -71,7 +72,7 @@ public abstract class OffsetScrollPositionHandlerMethodArgumentResolverSupport {
|
||||
* @param parameter can be {@literal null}.
|
||||
* @return the offset parameter
|
||||
*/
|
||||
protected String getOffsetParameter(@Nullable MethodParameter parameter) {
|
||||
protected String getOffsetParameter(MethodParameter parameter) {
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
@@ -89,19 +90,39 @@ public abstract class OffsetScrollPositionHandlerMethodArgumentResolverSupport {
|
||||
* Parses the given source into a {@link OffsetScrollPosition} instance.
|
||||
*
|
||||
* @param source could be {@literal null} or empty.
|
||||
* @return parsed OffsetScrollPosition
|
||||
* @return parsed OffsetScrollPosition or {@literal null} if it cannot be constructed.
|
||||
*/
|
||||
@Nullable
|
||||
OffsetScrollPosition parseParameterIntoOffsetScrollPosition(@Nullable List<String> source) {
|
||||
|
||||
// No parameter or Single empty parameter, e.g "offset="
|
||||
if (source == null || source.size() == 1 && !StringUtils.hasText(source.get(0))) {
|
||||
return ScrollPosition.offset();
|
||||
if (CollectionUtils.isEmpty(source) || (source.size() == 1 && !StringUtils.hasText(source.get(0)))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
long offset = Long.parseLong(source.get(0));
|
||||
return ScrollPosition.offset(offset);
|
||||
} catch (NumberFormatException ex) {
|
||||
return ScrollPosition.offset();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapt the given argument against the method parameter, if necessary.
|
||||
*
|
||||
* @param arg the resolved argument.
|
||||
* @param parameter the method parameter descriptor.
|
||||
* @return the adapted argument, or the original resolved argument as-is.
|
||||
*/
|
||||
@Nullable
|
||||
Object adaptArgumentIfNecessary(@Nullable Object arg, MethodParameter parameter) {
|
||||
|
||||
if (parameter.getParameterType() == Optional.class) {
|
||||
return arg == null ? Optional.empty() : Optional.of(arg);
|
||||
}
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2023 the original author or authors.
|
||||
* Copyright 2023 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.
|
||||
@@ -15,37 +15,36 @@
|
||||
*/
|
||||
package org.springframework.data.web;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.domain.OffsetScrollPosition;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.web.reactive.BindingContext;
|
||||
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.reactive.result.method.SyncHandlerMethodArgumentResolver;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Reactive {@link HandlerMethodArgumentResolver} to create {@link OffsetScrollPosition} instances from query string parameters.
|
||||
* Reactive {@link HandlerMethodArgumentResolver} to create {@link OffsetScrollPosition} instances from query string
|
||||
* parameters.
|
||||
*
|
||||
* @since 3.2
|
||||
* @author Yanming Zhou
|
||||
* @since 3.2
|
||||
*/
|
||||
public class ReactiveOffsetScrollPositionHandlerMethodArgumentResolver extends OffsetScrollPositionHandlerMethodArgumentResolverSupport
|
||||
implements SyncHandlerMethodArgumentResolver {
|
||||
public class ReactiveOffsetScrollPositionHandlerMethodArgumentResolver
|
||||
extends OffsetScrollPositionHandlerMethodArgumentResolverSupport implements SyncHandlerMethodArgumentResolver {
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(MethodParameter parameter) {
|
||||
return OffsetScrollPosition.class.equals(parameter.getParameterType());
|
||||
return OffsetScrollPosition.class.equals(parameter.nestedIfOptional().getNestedParameterType());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public OffsetScrollPosition resolveArgumentValue(MethodParameter parameter, BindingContext bindingContext,
|
||||
public Object resolveArgumentValue(MethodParameter parameter, BindingContext bindingContext,
|
||||
ServerWebExchange exchange) {
|
||||
|
||||
List<String> offsetParameter = exchange.getRequest().getQueryParams().get(getOffsetParameter(parameter));
|
||||
|
||||
return parseParameterIntoOffsetScrollPosition(offsetParameter);
|
||||
return adaptArgumentIfNecessary(parseParameterIntoOffsetScrollPosition(offsetParameter), parameter);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user