DATACMNS-470 - Removed code deprecated in version 1.6.
Removed support for Jackson 1 based repository populators in favor of Jackson 2 based ones. Removed PageableArgumentResolver in favor of PageableHandlerMethodArgumentResolver. Removed legacy setup code of the new HandlerMethodArgumentResolver implementations.
This commit is contained in:
@@ -21,7 +21,6 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.data.repository.init.Jackson2RepositoryPopulatorFactoryBean;
|
||||
import org.springframework.data.repository.init.JacksonRepositoryPopulatorFactoryBean;
|
||||
import org.springframework.data.repository.init.UnmarshallerRepositoryPopulatorFactoryBean;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
@@ -31,7 +30,6 @@ import org.w3c.dom.Element;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class ResourceReaderRepositoryPopulatorBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
/*
|
||||
@@ -45,8 +43,6 @@ public class ResourceReaderRepositoryPopulatorBeanDefinitionParser extends Abstr
|
||||
|
||||
if ("unmarshaller-populator".equals(name)) {
|
||||
return UnmarshallerRepositoryPopulatorFactoryBean.class.getName();
|
||||
} else if ("jackson-populator".equals(name)) {
|
||||
return JacksonRepositoryPopulatorFactoryBean.class.getName();
|
||||
} else if ("jackson2-populator".equals(name)) {
|
||||
return Jackson2RepositoryPopulatorFactoryBean.class.getName();
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2014 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
|
||||
*
|
||||
* http://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.repository.init;
|
||||
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
|
||||
/**
|
||||
* {@link FactoryBean} to set up a {@link ResourceReaderRepositoryPopulator} with a {@link JacksonResourceReader}.
|
||||
*
|
||||
* @deprecated use {@link Jackson2RepositoryPopulatorFactoryBean} instead
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Deprecated
|
||||
public class JacksonRepositoryPopulatorFactoryBean extends AbstractRepositoryPopulatorFactoryBean {
|
||||
|
||||
private ObjectMapper mapper;
|
||||
|
||||
/**
|
||||
* Configures the {@link ObjectMapper} to be used.
|
||||
*
|
||||
* @param mapper
|
||||
*/
|
||||
public void setMapper(ObjectMapper mapper) {
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.init.AbstractRepositoryPopulatorFactoryBean#getResourceReader()
|
||||
*/
|
||||
@Override
|
||||
protected ResourceReader getResourceReader() {
|
||||
return new JacksonResourceReader(mapper);
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2014 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
|
||||
*
|
||||
* http://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.repository.init;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.codehaus.jackson.JsonNode;
|
||||
import org.codehaus.jackson.map.DeserializationConfig.Feature;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* A {@link ResourceReader} using Jackson to read JSON into objects.
|
||||
*
|
||||
* @deprecated use {@link Jackson2ResourceReader} instead.
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Deprecated
|
||||
public class JacksonResourceReader implements ResourceReader {
|
||||
|
||||
private static final String DEFAULT_TYPE_KEY = "_class";
|
||||
private static final ObjectMapper DEFAULT_MAPPER = new ObjectMapper();
|
||||
|
||||
static {
|
||||
DEFAULT_MAPPER.configure(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
}
|
||||
|
||||
private final ObjectMapper mapper;
|
||||
private String typeKey = DEFAULT_TYPE_KEY;
|
||||
|
||||
/**
|
||||
* Creates a new {@link JacksonResourceReader}.
|
||||
*/
|
||||
public JacksonResourceReader() {
|
||||
this(DEFAULT_MAPPER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link JacksonResourceReader} using the given {@link ObjectMapper}.
|
||||
*
|
||||
* @param mapper
|
||||
*/
|
||||
public JacksonResourceReader(ObjectMapper mapper) {
|
||||
this.mapper = mapper == null ? DEFAULT_MAPPER : mapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the JSON document's key to lookup the type to instantiate the object. Defaults to
|
||||
* {@link JacksonResourceReader#DEFAULT_TYPE_KEY}.
|
||||
*
|
||||
* @param typeKey
|
||||
*/
|
||||
public void setTypeKey(String typeKey) {
|
||||
this.typeKey = typeKey;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.init.ResourceReader#readFrom(org.springframework.core.io.Resource, java.lang.ClassLoader)
|
||||
*/
|
||||
public Object readFrom(Resource resource, ClassLoader classLoader) throws Exception {
|
||||
|
||||
InputStream stream = resource.getInputStream();
|
||||
JsonNode node = mapper.reader(JsonNode.class).readTree(stream);
|
||||
|
||||
if (node.isArray()) {
|
||||
|
||||
Iterator<JsonNode> elements = node.getElements();
|
||||
List<Object> result = new ArrayList<Object>();
|
||||
|
||||
while (elements.hasNext()) {
|
||||
JsonNode element = elements.next();
|
||||
result.add(readSingle(element, classLoader));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return readSingle(node, classLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the given {@link JsonNode} into an instance of the type encoded in it using the configured type key.
|
||||
*
|
||||
* @param node must not be {@literal null}.
|
||||
* @param classLoader
|
||||
* @return
|
||||
*/
|
||||
private Object readSingle(JsonNode node, ClassLoader classLoader) throws IOException {
|
||||
|
||||
JsonNode typeNode = node.findValue(typeKey);
|
||||
String typeName = typeNode == null ? null : typeNode.asText();
|
||||
|
||||
Class<?> type = ClassUtils.resolveClassName(typeName, classLoader);
|
||||
|
||||
return mapper.reader(type).readValue(node);
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,6 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.hateoas.TemplateVariable;
|
||||
import org.springframework.hateoas.TemplateVariable.VariableType;
|
||||
@@ -40,32 +39,11 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||
* @author Oliver Gierke
|
||||
* @author Nick Williams
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class HateoasPageableHandlerMethodArgumentResolver extends PageableHandlerMethodArgumentResolver implements
|
||||
UriComponentsContributor {
|
||||
|
||||
/**
|
||||
* A {@link HateoasPageableHandlerMethodArgumentResolver} preconfigured to the setup of
|
||||
* {@link PageableArgumentResolver}. Use that if you need to stick to the former request parameters an 1-indexed
|
||||
* behavior. This will be removed in the next major version (1.7). So consider migrating to the new way of exposing
|
||||
* request parameters.
|
||||
*/
|
||||
@Deprecated public static final HateoasPageableHandlerMethodArgumentResolver LEGACY;
|
||||
private static final HateoasSortHandlerMethodArgumentResolver DEFAULT_SORT_RESOLVER = new HateoasSortHandlerMethodArgumentResolver();
|
||||
|
||||
static {
|
||||
|
||||
HateoasSortHandlerMethodArgumentResolver LEGACY_SORT = new HateoasSortHandlerMethodArgumentResolver();
|
||||
LEGACY_SORT.setLegacyMode(true);
|
||||
LEGACY_SORT.setSortParameter("page.sort");
|
||||
|
||||
LEGACY = new HateoasPageableHandlerMethodArgumentResolver(LEGACY_SORT);
|
||||
LEGACY.setPageParameterName("page.page");
|
||||
LEGACY.setSizeParameterName("page.size");
|
||||
LEGACY.setFallbackPageable(new PageRequest(1, 10));
|
||||
LEGACY.setOneIndexedParameters(true);
|
||||
}
|
||||
|
||||
private final HateoasSortHandlerMethodArgumentResolver sortResolver;
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,15 +17,12 @@ package org.springframework.data.web;
|
||||
|
||||
import static org.springframework.hateoas.TemplateVariable.VariableType.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.hateoas.TemplateVariable;
|
||||
import org.springframework.hateoas.TemplateVariable.VariableType;
|
||||
import org.springframework.hateoas.TemplateVariables;
|
||||
import org.springframework.hateoas.mvc.UriComponentsContributor;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
@@ -78,21 +75,10 @@ public class HateoasSortHandlerMethodArgumentResolver extends SortHandlerMethodA
|
||||
Sort sort = (Sort) value;
|
||||
String sortParameter = getSortParameter(parameter);
|
||||
|
||||
if (legacyMode) {
|
||||
builder.replaceQueryParam(sortParameter);
|
||||
|
||||
List<String> expressions = legacyFoldExpressions(sort);
|
||||
Assert.isTrue(expressions.size() == 2,
|
||||
String.format("Expected 2 sort expressions (fields, direction) but got %d!", expressions.size()));
|
||||
builder.replaceQueryParam(sortParameter, expressions.get(0));
|
||||
builder.replaceQueryParam(getLegacyDirectionParameter(parameter), expressions.get(1));
|
||||
|
||||
} else {
|
||||
|
||||
builder.replaceQueryParam(sortParameter);
|
||||
|
||||
for (String expression : foldIntoExpressions(sort)) {
|
||||
builder.queryParam(sortParameter, expression);
|
||||
}
|
||||
for (String expression : foldIntoExpressions(sort)) {
|
||||
builder.queryParam(sortParameter, expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008-2013 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
|
||||
*
|
||||
* http://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.web;
|
||||
|
||||
import static org.springframework.data.web.SpringDataAnnotationUtils.*;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.validation.DataBinder;
|
||||
import org.springframework.web.bind.ServletRequestDataBinder;
|
||||
import org.springframework.web.bind.ServletRequestParameterPropertyValues;
|
||||
import org.springframework.web.bind.support.WebArgumentResolver;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
|
||||
/**
|
||||
* Extracts paging information from web requests and thus allows injecting {@link Pageable} instances into controller
|
||||
* methods. Request properties to be parsed can be configured. Default configuration uses request properties beginning
|
||||
* with {@link #DEFAULT_PREFIX}{@link #DEFAULT_SEPARATOR}.
|
||||
*
|
||||
* @deprecated use {@link PageableHandlerMethodArgumentResolver} instead.
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Deprecated
|
||||
public class PageableArgumentResolver implements WebArgumentResolver {
|
||||
|
||||
private static final Pageable DEFAULT_PAGE_REQUEST = new PageRequest(0, 10);
|
||||
private static final String DEFAULT_PREFIX = "page";
|
||||
private static final String DEFAULT_SEPARATOR = ".";
|
||||
|
||||
private Pageable fallbackPageable = DEFAULT_PAGE_REQUEST;
|
||||
private String prefix = DEFAULT_PREFIX;
|
||||
private String separator = DEFAULT_SEPARATOR;
|
||||
|
||||
/**
|
||||
* Setter to configure a fallback instance of {@link Pageable} that is being used to back missing parameters. Defaults
|
||||
* to {@link #DEFAULT_PAGE_REQUEST}.
|
||||
*
|
||||
* @param fallbackPageable the fallbackPageable to set
|
||||
*/
|
||||
public void setFallbackPageable(Pageable fallbackPageable) {
|
||||
this.fallbackPageable = null == fallbackPageable ? DEFAULT_PAGE_REQUEST : fallbackPageable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter to configure the prefix of request parameters to be used to retrieve paging information. Defaults to
|
||||
* {@link #DEFAULT_PREFIX}.
|
||||
*
|
||||
* @param prefix the prefix to set
|
||||
*/
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = null == prefix ? DEFAULT_PREFIX : prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter to configure the separator between prefix and actual property value. Defaults to {@link #DEFAULT_SEPARATOR}.
|
||||
*
|
||||
* @param separator the separator to set
|
||||
*/
|
||||
public void setSeparator(String separator) {
|
||||
this.separator = null == separator ? DEFAULT_SEPARATOR : separator;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.bind.support.WebArgumentResolver#resolveArgument(org.springframework.core.MethodParameter, org.springframework.web.context.request.NativeWebRequest)
|
||||
*/
|
||||
public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) {
|
||||
|
||||
if (methodParameter.getParameterType().equals(Pageable.class)) {
|
||||
|
||||
assertPageableUniqueness(methodParameter);
|
||||
|
||||
Pageable request = getDefaultFromAnnotationOrFallback(methodParameter);
|
||||
ServletRequest servletRequest = (ServletRequest) webRequest.getNativeRequest();
|
||||
PropertyValues propertyValues = new ServletRequestParameterPropertyValues(servletRequest,
|
||||
getPrefix(methodParameter), separator);
|
||||
|
||||
DataBinder binder = new ServletRequestDataBinder(request);
|
||||
|
||||
binder.initDirectFieldAccess();
|
||||
binder.registerCustomEditor(Sort.class, new SortPropertyEditor("sort.dir", propertyValues));
|
||||
binder.bind(propertyValues);
|
||||
|
||||
if (request.getPageNumber() > 0) {
|
||||
request = new PageRequest(request.getPageNumber() - 1, request.getPageSize(), request.getSort());
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
return UNRESOLVED;
|
||||
}
|
||||
|
||||
private Pageable getDefaultFromAnnotationOrFallback(MethodParameter methodParameter) {
|
||||
|
||||
// search for PageableDefaults annotation
|
||||
for (Annotation annotation : methodParameter.getParameterAnnotations()) {
|
||||
if (annotation instanceof PageableDefaults) {
|
||||
return getDefaultPageRequestFrom((PageableDefaults) annotation);
|
||||
}
|
||||
}
|
||||
|
||||
// Construct request with fallback request to ensure sensible
|
||||
// default values. Create fresh copy as Spring will manipulate the
|
||||
// instance under the covers
|
||||
return new PageRequest(fallbackPageable.getPageNumber(), fallbackPageable.getPageSize(), fallbackPageable.getSort());
|
||||
}
|
||||
|
||||
static Pageable getDefaultPageRequestFrom(PageableDefaults defaults) {
|
||||
|
||||
// +1 is because we substract 1 later
|
||||
int defaultPageNumber = defaults.pageNumber() + 1;
|
||||
int defaultPageSize = defaults.value();
|
||||
|
||||
if (defaults.sort().length == 0) {
|
||||
return new PageRequest(defaultPageNumber, defaultPageSize);
|
||||
}
|
||||
|
||||
return new PageRequest(defaultPageNumber, defaultPageSize, defaults.sortDir(), defaults.sort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the prefix to use to bind properties from. Will prepend a possible {@link Qualifier} if available or
|
||||
* return the configured prefix otherwise.
|
||||
*
|
||||
* @param parameter
|
||||
* @return
|
||||
*/
|
||||
private String getPrefix(MethodParameter parameter) {
|
||||
|
||||
for (Annotation annotation : parameter.getParameterAnnotations()) {
|
||||
if (annotation instanceof Qualifier) {
|
||||
return new StringBuilder(((Qualifier) annotation).value()).append("_").append(prefix).toString();
|
||||
}
|
||||
}
|
||||
|
||||
return prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link java.beans.PropertyEditor} to create {@link Sort} instances from textual representations. The implementation
|
||||
* interprets the string as a comma separated list where the first entry is the sort direction ( {@code asc},
|
||||
* {@code desc}) followed by the properties to sort by.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class SortPropertyEditor extends PropertyEditorSupport {
|
||||
|
||||
private final String orderProperty;
|
||||
private final PropertyValues values;
|
||||
|
||||
/**
|
||||
* Creates a new {@link SortPropertyEditor}.
|
||||
*
|
||||
* @param orderProperty
|
||||
* @param values
|
||||
*/
|
||||
public SortPropertyEditor(String orderProperty, PropertyValues values) {
|
||||
|
||||
this.orderProperty = orderProperty;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void setAsText(String text) {
|
||||
|
||||
PropertyValue rawOrder = values.getPropertyValue(orderProperty);
|
||||
Direction order = null == rawOrder ? Direction.ASC : Direction.fromString(rawOrder.getValue().toString());
|
||||
|
||||
setValue(new Sort(order, text));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008-2013 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
|
||||
*
|
||||
* http://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.web;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
|
||||
/**
|
||||
* Annotation to set defaults when injecting a {@link org.springframework.data.domain.Pageable} into a controller
|
||||
* method.
|
||||
*
|
||||
* @deprecated use {@link PageableDefault} instead.
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.PARAMETER)
|
||||
@Deprecated
|
||||
public @interface PageableDefaults {
|
||||
|
||||
/**
|
||||
* The default-size the injected {@link org.springframework.data.domain.Pageable} should get if no corresponding
|
||||
* parameter defined in request (default is 10).
|
||||
*/
|
||||
int value() default 10;
|
||||
|
||||
/**
|
||||
* The default-pagenumber the injected {@link org.springframework.data.domain.Pageable} should get if no corresponding
|
||||
* parameter defined in request (default is 0).
|
||||
*/
|
||||
int pageNumber() default 0;
|
||||
|
||||
/**
|
||||
* The properties to sort by by default. If unset, no sorting will be applied at all.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String[] sort() default {};
|
||||
|
||||
/**
|
||||
* The direction to sort by. Defaults to {@link Direction#ASC}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Direction sortDir() default Direction.ASC;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
* Copyright 2013-2014 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.
|
||||
@@ -40,28 +40,10 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
* @author Oliver Gierke
|
||||
* @author Nick Williams
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class PageableHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
private static final String INVALID_DEFAULT_PAGE_SIZE = "Invalid default page size configured for method %s! Must not be less than one!";
|
||||
|
||||
/**
|
||||
* A {@link PageableHandlerMethodArgumentResolver} preconfigured to the setup of {@link PageableArgumentResolver}. Use
|
||||
* that if you need to stick to the former request parameters an 1-indexed behavior. This will be removed in the next
|
||||
* major version (1.7). So consider migrating to the new way of exposing request parameters.
|
||||
*/
|
||||
@Deprecated public static final PageableHandlerMethodArgumentResolver LEGACY;
|
||||
|
||||
static {
|
||||
LEGACY = new PageableHandlerMethodArgumentResolver();
|
||||
LEGACY.pageParameterName = "page.page";
|
||||
LEGACY.sizeParameterName = "page.size";
|
||||
LEGACY.fallbackPageable = new PageRequest(1, 10);
|
||||
LEGACY.oneIndexedParameters = true;
|
||||
LEGACY.sortResolver.setLegacyMode(true);
|
||||
LEGACY.sortResolver.setSortParameter("page.sort");
|
||||
}
|
||||
|
||||
private static final String DEFAULT_PAGE_PARAMETER = "page";
|
||||
private static final String DEFAULT_SIZE_PARAMETER = "size";
|
||||
private static final String DEFAULT_PREFIX = "";
|
||||
@@ -270,12 +252,6 @@ public class PageableHandlerMethodArgumentResolver implements HandlerMethodArgum
|
||||
|
||||
private Pageable getDefaultFromAnnotationOrFallback(MethodParameter methodParameter) {
|
||||
|
||||
if (sortResolver.legacyMode && methodParameter.hasParameterAnnotation(PageableDefaults.class)) {
|
||||
Pageable pageable = PageableArgumentResolver.getDefaultPageRequestFrom(methodParameter
|
||||
.getParameterAnnotation(PageableDefaults.class));
|
||||
return new PageRequest(pageable.getPageNumber() - 1, pageable.getPageSize(), pageable.getSort());
|
||||
}
|
||||
|
||||
if (methodParameter.hasParameterAnnotation(PageableDefault.class)) {
|
||||
return getDefaultPageRequestFrom(methodParameter);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
* Copyright 2013-2014 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.
|
||||
@@ -29,7 +29,6 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
@@ -57,19 +56,6 @@ public class SortHandlerMethodArgumentResolver implements HandlerMethodArgumentR
|
||||
private String propertyDelimiter = DEFAULT_PROPERTY_DELIMITER;
|
||||
private String qualifierDelimiter = DEFAULT_QUALIFIER_DELIMITER;
|
||||
|
||||
boolean legacyMode = false;
|
||||
|
||||
/**
|
||||
* Enables legacy mode parsing of the sorting parameter from the incoming request. Uses the sort property configured
|
||||
* to lookup the fields to sort on and {@code $sortParameter.dir} for the direction.
|
||||
*
|
||||
* @param legacyMode whether to enable the legacy mode or not.
|
||||
*/
|
||||
@Deprecated
|
||||
void setLegacyMode(boolean legacyMode) {
|
||||
this.legacyMode = legacyMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the request parameter to lookup sort information from. Defaults to {@code sort}.
|
||||
*
|
||||
@@ -123,8 +109,7 @@ public class SortHandlerMethodArgumentResolver implements HandlerMethodArgumentR
|
||||
String[] directionParameter = webRequest.getParameterValues(getSortParameter(parameter));
|
||||
|
||||
if (directionParameter != null && directionParameter.length != 0) {
|
||||
return legacyMode ? parseLegacyParameterIntoSort(webRequest, parameter) : parseParameterIntoSort(
|
||||
directionParameter, propertyDelimiter);
|
||||
return parseParameterIntoSort(directionParameter, propertyDelimiter);
|
||||
} else {
|
||||
return getDefaultFromAnnotationOrFallback(parameter);
|
||||
}
|
||||
@@ -202,27 +187,6 @@ public class SortHandlerMethodArgumentResolver implements HandlerMethodArgumentR
|
||||
return builder.append(sortParameter).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Sort} instance from the given request expecting the {@link Direction} being encoded in a parameter
|
||||
* with an appended {@code .dir}.
|
||||
*
|
||||
* @param request must not be {@literal null}.
|
||||
* @param parameter must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
private Sort parseLegacyParameterIntoSort(WebRequest request, MethodParameter parameter) {
|
||||
|
||||
String property = getSortParameter(parameter);
|
||||
String fields = request.getParameter(property);
|
||||
String directions = request.getParameter(getLegacyDirectionParameter(parameter));
|
||||
|
||||
return new Sort(Direction.fromStringOrNull(directions), fields.split(","));
|
||||
}
|
||||
|
||||
protected String getLegacyDirectionParameter(MethodParameter parameter) {
|
||||
return getSortParameter(parameter) + ".dir";
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given sort expressions into a {@link Sort} instance. The implementation expects the sources to be a
|
||||
* concatenation of Strings using the given delimiter. If the last element can be parsed into a {@link Direction} it's
|
||||
@@ -376,13 +340,8 @@ public class SortHandlerMethodArgumentResolver implements HandlerMethodArgumentR
|
||||
return expressions;
|
||||
}
|
||||
|
||||
if (legacyMode) {
|
||||
expressions.add(StringUtils.collectionToDelimitedString(elements, propertyDelimiter));
|
||||
expressions.add(direction.name().toLowerCase());
|
||||
} else {
|
||||
elements.add(direction.name().toLowerCase());
|
||||
expressions.add(StringUtils.collectionToDelimitedString(elements, propertyDelimiter));
|
||||
}
|
||||
elements.add(direction.name().toLowerCase());
|
||||
expressions.add(StringUtils.collectionToDelimitedString(elements, propertyDelimiter));
|
||||
|
||||
return expressions;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<xsd:schema xmlns="http://www.springframework.org/schema/data/repository"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
targetNamespace="http://www.springframework.org/schema/data/repository"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/context"
|
||||
schemaLocation="http://www.springframework.org/schema/context/spring-context.xsd" />
|
||||
|
||||
<xsd:complexType name="repositories">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="include-filter" type="context:filterType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Controls which eligible types to include for component scanning.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="exclude-filter" type="context:filterType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Controls which eligible types to exclude for component scanning.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="base-package" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines the base package where the DAO interface will be tried to be detected.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="named-queries-location" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines the location to look for a Properties file containing externally defined queries.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="consider-nested-repositories" type="xsd:boolean" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Controls whether nested repository interface definitions should be considered.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="populator">
|
||||
<xsd:attribute name="locations" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Where to find the files to read the objects from the repository shall be populated with.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<!-- XML (Unmarshaller) initializer -->
|
||||
|
||||
<xsd:element name="unmarshaller-populator">
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="populator">
|
||||
<xsd:attribute name="unmarshaller-ref" type="unmarshallerRefType" use="required" />
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:simpleType name="unmarshallerRefType">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:expected-type type="org.springframework.oxm.Unmarshaller" />
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
|
||||
<!-- JSON (Jackson2) initializer -->
|
||||
|
||||
<xsd:element name="jackson2-populator">
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="populator">
|
||||
<xsd:attribute name="object-mapper-ref" type="objectMapper2Type" />
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:simpleType name="objectMapper2Type">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:expected-type type="com.fasterxml.jackson.databind.ObjectMapper" />
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string" />
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:attributeGroup name="repository-attributes">
|
||||
<xsd:attribute name="repository-impl-postfix" type="xsd:string"/>
|
||||
<xsd:attribute name="query-lookup-strategy" type="query-strategy"/>
|
||||
<xsd:attribute name="factory-class" type="classType"/>
|
||||
</xsd:attributeGroup>
|
||||
|
||||
<xsd:attributeGroup name="transactional-repository-attributes">
|
||||
<xsd:attributeGroup ref="repository-attributes"/>
|
||||
<xsd:attribute name="transaction-manager-ref" type="transactionManagerRef"/>
|
||||
</xsd:attributeGroup>
|
||||
|
||||
<xsd:attributeGroup name="auditing-attributes">
|
||||
<xsd:attribute name="auditor-aware-ref">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
References a bean of type AuditorAware to represent the current principal.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.domain.AuditorAware" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="set-dates" default="true" type="xsd:boolean">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Configures whether the creation and modification dates are set.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="date-time-provider-ref">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Configures a DateTimeProvider that allows customizing which DateTime shall be used for setting
|
||||
creation and modification dates.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.jpa.domain.support.DateTimeProvider" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="modify-on-creation" default="true" type="xsd:boolean">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Configures whether the entity shall be marked as modified on creation.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:attributeGroup>
|
||||
|
||||
<xsd:simpleType name="query-strategy">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Determines the way query methods are being executed.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="create-if-not-found">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Tries to find a named query but creates a custom query if
|
||||
none can be found. (Default)
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
<xsd:enumeration value="create">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Creates a query from the query method's name.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
<xsd:enumeration value="use-declared-query">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Uses a declared query to execute. Fails if no
|
||||
declared query (either through named query or through @Query)
|
||||
is defined.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:enumeration>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="customImplementationReference">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref"/>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="entityManagerFactoryRef">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.orm.jpa.AbstractEntityManagerFactoryBean"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="transactionManagerRef">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.transaction.PlatformTransactionManager"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="classType">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="direct">
|
||||
<tool:expected-type type="java.lang.Class"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
</xsd:schema>
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2014 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.
|
||||
@@ -27,7 +27,6 @@ import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.core.SpringVersion;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.repository.init.Jackson2ResourceReader;
|
||||
import org.springframework.data.repository.init.JacksonResourceReader;
|
||||
import org.springframework.data.repository.init.ResourceReaderRepositoryPopulator;
|
||||
import org.springframework.data.repository.init.UnmarshallingResourceReader;
|
||||
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
|
||||
@@ -41,28 +40,6 @@ import org.springframework.test.util.ReflectionTestUtils;
|
||||
*/
|
||||
public class ResourceReaderRepositoryPopulatorBeanDefinitionParserIntegrationTests {
|
||||
|
||||
/**
|
||||
* @see DATACMNS-58
|
||||
*/
|
||||
@Test
|
||||
public void registersJacksonInitializerCorrectly() {
|
||||
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
|
||||
reader.loadBeanDefinitions(getPopulatorResource());
|
||||
|
||||
BeanDefinition definition = beanFactory.getBeanDefinition("jackson-populator");
|
||||
assertThat(definition, is(notNullValue()));
|
||||
|
||||
Object bean = beanFactory.getBean("jackson-populator");
|
||||
assertThat(bean, is(instanceOf(ResourceReaderRepositoryPopulator.class)));
|
||||
Object resourceReader = ReflectionTestUtils.getField(bean, "reader");
|
||||
assertThat(resourceReader, is(instanceOf(JacksonResourceReader.class)));
|
||||
|
||||
Object resources = ReflectionTestUtils.getField(bean, "resources");
|
||||
assertIsListOfClasspathResourcesWithPath(resources, "org/springframework/data/repository/init/data.json");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-333
|
||||
*/
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012 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
|
||||
*
|
||||
* http://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.repository.init;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link JacksonResourceReader}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class JacksonResourceReaderIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void readsFileWithMultipleObjects() throws Exception {
|
||||
|
||||
ResourceReader reader = new JacksonResourceReader();
|
||||
Object result = reader.readFrom(new ClassPathResource("data.json", getClass()), null);
|
||||
|
||||
assertThat(result, is(instanceOf(Collection.class)));
|
||||
assertThat((Collection<?>) result, hasSize(1));
|
||||
}
|
||||
}
|
||||
@@ -1,256 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 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
|
||||
*
|
||||
* http://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.web;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.web.PageableHandlerMethodArgumentResolver.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.web.SortDefault.SortDefaults;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link PageableHandlerMethodArgumentResolver} in it's legacy mode. Essentially a copy of
|
||||
* {@link PageableArgumentResolverUnitTests} but but executed against {@link PageableHandlerMethodArgumentResolver}.
|
||||
*
|
||||
* @since 1.6
|
||||
* @author Oliver Gierke
|
||||
* @author Nick Williams
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class LegacyPageableHandlerMethodArgumentResolverUnitTests extends PageableDefaultUnitTests {
|
||||
|
||||
Method correctMethod, noQualifiers, invalidQualifiers, defaultsMethod, defaultsMethodWithSort,
|
||||
defaultsMethodWithSortAndDirection, otherMethod;
|
||||
|
||||
MockHttpServletRequest request;
|
||||
|
||||
@Before
|
||||
public void setUp() throws SecurityException, NoSuchMethodException {
|
||||
|
||||
correctMethod = SampleController.class.getMethod("correctMethod", Pageable.class, Pageable.class);
|
||||
noQualifiers = SampleController.class.getMethod("noQualifiers", Pageable.class, Pageable.class);
|
||||
invalidQualifiers = SampleController.class.getMethod("invalidQualifiers", Pageable.class, Pageable.class);
|
||||
otherMethod = SampleController.class.getMethod("unsupportedMethod", String.class);
|
||||
|
||||
defaultsMethod = SampleController.class.getMethod("simpleDefault", Pageable.class);
|
||||
defaultsMethodWithSort = SampleController.class.getMethod("simpleDefaultWithSort", Pageable.class);
|
||||
defaultsMethodWithSortAndDirection = SampleController.class.getMethod("simpleDefaultWithSortAndDirection",
|
||||
Pageable.class);
|
||||
|
||||
request = new MockHttpServletRequest();
|
||||
|
||||
// Add pagination info for foo table
|
||||
request.addParameter("foo_page.size", "50");
|
||||
request.addParameter("foo_page.sort", "foo");
|
||||
request.addParameter("foo_page.sort.dir", "asc");
|
||||
|
||||
// Add pagination info for bar table
|
||||
request.addParameter("bar_page.size", "60");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsPageableParameter() {
|
||||
|
||||
PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
|
||||
resolver.supportsParameter(new MethodParameter(correctMethod, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotSupportNonPageableParameter() {
|
||||
|
||||
PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
|
||||
resolver.supportsParameter(new MethodParameter(otherMethod, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testname() throws Exception {
|
||||
|
||||
assertSizeForPrefix(50, new Sort(Direction.ASC, "foo"), 0);
|
||||
assertSizeForPrefix(60, null, 1);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void rejectsInvalidlyMappedPageables() throws Exception {
|
||||
|
||||
MethodParameter parameter = new MethodParameter(noQualifiers, 0);
|
||||
NativeWebRequest webRequest = new ServletWebRequest(request);
|
||||
|
||||
new PageableHandlerMethodArgumentResolver().resolveArgument(parameter, null, webRequest, null);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void rejectsInvalidQualifiers() throws Exception {
|
||||
|
||||
MethodParameter parameter = new MethodParameter(invalidQualifiers, 0);
|
||||
NativeWebRequest webRequest = new ServletWebRequest(request);
|
||||
|
||||
new PageableHandlerMethodArgumentResolver().resolveArgument(parameter, null, webRequest, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertDefaults() throws Exception {
|
||||
|
||||
Object argument = setupAndResolve(defaultsMethod);
|
||||
|
||||
assertThat(argument, is(instanceOf(Pageable.class)));
|
||||
|
||||
Pageable pageable = (Pageable) argument;
|
||||
assertThat(pageable.getPageSize(), is(PAGE_SIZE));
|
||||
assertThat(pageable.getPageNumber(), is(PAGE_NUMBER));
|
||||
assertThat(pageable.getSort(), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertOverridesDefaults() throws Exception {
|
||||
|
||||
Integer sizeParam = 5;
|
||||
|
||||
MethodParameter parameter = new MethodParameter(defaultsMethod, 0);
|
||||
MockHttpServletRequest mockRequest = new MockHttpServletRequest();
|
||||
|
||||
mockRequest.addParameter("page.page", sizeParam.toString());
|
||||
NativeWebRequest webRequest = new ServletWebRequest(mockRequest);
|
||||
Object argument = LEGACY.resolveArgument(parameter, null, webRequest, null);
|
||||
|
||||
assertTrue(argument instanceof Pageable);
|
||||
|
||||
Pageable pageable = (Pageable) argument;
|
||||
assertEquals(PAGE_SIZE, pageable.getPageSize());
|
||||
assertEquals(sizeParam - 1, pageable.getPageNumber());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appliesDefaultSort() throws Exception {
|
||||
|
||||
Object argument = setupAndResolve(defaultsMethodWithSort);
|
||||
|
||||
assertThat(argument, is(instanceOf(Pageable.class)));
|
||||
|
||||
Pageable pageable = (Pageable) argument;
|
||||
assertThat(pageable.getPageSize(), is(PAGE_SIZE));
|
||||
assertThat(pageable.getPageNumber(), is(PAGE_NUMBER));
|
||||
assertThat(pageable.getSort(), is(new Sort("firstname", "lastname")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appliesDefaultSortAndDirection() throws Exception {
|
||||
|
||||
Object argument = setupAndResolve(defaultsMethodWithSortAndDirection);
|
||||
|
||||
assertThat(argument, is(instanceOf(Pageable.class)));
|
||||
|
||||
Pageable pageable = (Pageable) argument;
|
||||
assertThat(pageable.getPageSize(), is(PAGE_SIZE));
|
||||
assertThat(pageable.getPageNumber(), is(PAGE_NUMBER));
|
||||
assertThat(pageable.getSort(), is(new Sort(Direction.DESC, "firstname", "lastname")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildsUpRequestParameters() {
|
||||
|
||||
// Set up basic page representation based on 1-indexed page numbers
|
||||
String basicString = String.format("page.page=%d&page.size=%d", PAGE_NUMBER + 1, PAGE_SIZE);
|
||||
|
||||
assertUriStringFor(REFERENCE_WITHOUT_SORT, basicString);
|
||||
assertUriStringFor(REFERENCE_WITH_SORT, basicString + "&page.sort=firstname,lastname&page.sort.dir=desc");
|
||||
assertUriStringFor(REFERENCE_WITH_SORT_FIELDS, basicString + "&page.sort=firstname,lastname&page.sort.dir=asc");
|
||||
}
|
||||
|
||||
private void assertSizeForPrefix(int size, Sort sort, int index) throws Exception {
|
||||
|
||||
MethodParameter parameter = new MethodParameter(correctMethod, index);
|
||||
NativeWebRequest webRequest = new ServletWebRequest(request);
|
||||
|
||||
Object argument = LEGACY.resolveArgument(parameter, null, webRequest, null);
|
||||
assertThat(argument, is(instanceOf(Pageable.class)));
|
||||
|
||||
Pageable pageable = (Pageable) argument;
|
||||
assertThat(pageable.getPageSize(), is(size));
|
||||
|
||||
if (null != sort) {
|
||||
assertThat(pageable.getSort(), is(sort));
|
||||
}
|
||||
}
|
||||
|
||||
private Object setupAndResolve(Method method) throws Exception {
|
||||
|
||||
MethodParameter parameter = new MethodParameter(method, 0);
|
||||
NativeWebRequest webRequest = new ServletWebRequest(new MockHttpServletRequest());
|
||||
|
||||
return LEGACY.resolveArgument(parameter, null, webRequest, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> getControllerClass() {
|
||||
return SampleController.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HateoasPageableHandlerMethodArgumentResolver getResolver() {
|
||||
return HateoasPageableHandlerMethodArgumentResolver.LEGACY;
|
||||
}
|
||||
|
||||
protected void assertUriStringFor(Pageable pageable, String expected) {
|
||||
|
||||
UriComponentsBuilder builder = UriComponentsBuilder.fromPath("/");
|
||||
MethodParameter parameter = getParameterOfMethod("supportedMethod");
|
||||
|
||||
getResolver().enhance(builder, parameter, pageable);
|
||||
|
||||
assertThat(builder.build().toUriString(), endsWith(expected));
|
||||
}
|
||||
|
||||
static interface SampleController {
|
||||
|
||||
void simpleDefault(@PageableDefaults(value = PAGE_SIZE, pageNumber = PAGE_NUMBER) Pageable pageable);
|
||||
|
||||
void simpleDefaultWithSort(@PageableDefaults(value = PAGE_SIZE, pageNumber = PAGE_NUMBER, sort = { "firstname",
|
||||
"lastname" }) Pageable pageable);
|
||||
|
||||
void simpleDefaultWithSortAndDirection(@PageableDefaults(value = PAGE_SIZE, pageNumber = PAGE_NUMBER, sort = {
|
||||
"firstname", "lastname" }, sortDir = Direction.DESC) Pageable pageable);
|
||||
|
||||
void simpleDefaultWithExternalSort(@PageableDefaults(value = PAGE_SIZE, pageNumber = PAGE_NUMBER) @SortDefault(
|
||||
sort = { "firstname", "lastname" }, direction = Direction.DESC) Pageable pageable);
|
||||
|
||||
void simpleDefaultWithContaineredExternalSort(
|
||||
@PageableDefaults(value = PAGE_SIZE, pageNumber = PAGE_NUMBER) @SortDefaults(@SortDefault(sort = { "firstname",
|
||||
"lastname" }, direction = Direction.DESC)) Pageable pageable);
|
||||
|
||||
void correctMethod(@Qualifier("foo") Pageable first, @Qualifier("bar") Pageable second);
|
||||
|
||||
void invalidQualifiers(@Qualifier("foo") Pageable first, @Qualifier("foo") Pageable second);
|
||||
|
||||
void noQualifiers(Pageable first, Pageable second);
|
||||
|
||||
void supportedMethod(Pageable pageable);
|
||||
|
||||
void unsupportedMethod(String foo);
|
||||
}
|
||||
}
|
||||
@@ -1,218 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008-2012 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
|
||||
*
|
||||
* http://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.web;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
|
||||
/**
|
||||
* Unit test for {@link PageableArgumentResolver}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class PageableArgumentResolverUnitTests {
|
||||
|
||||
Method correctMethod, failedMethod, invalidQualifiers, defaultsMethod, defaultsMethodWithSort,
|
||||
defaultsMethodWithSortAndDirection;
|
||||
|
||||
MockHttpServletRequest request;
|
||||
|
||||
@Before
|
||||
public void setUp() throws SecurityException, NoSuchMethodException {
|
||||
|
||||
correctMethod = SampleController.class.getMethod("correctMethod", Pageable.class, Pageable.class);
|
||||
failedMethod = SampleController.class.getMethod("noQualifiers", Pageable.class, Pageable.class);
|
||||
invalidQualifiers = SampleController.class.getMethod("invalidQualifiers", Pageable.class, Pageable.class);
|
||||
|
||||
defaultsMethod = SampleController.class.getMethod("defaultsMethod", Pageable.class);
|
||||
defaultsMethodWithSort = SampleController.class.getMethod("defaultsMethodWithSort", Pageable.class);
|
||||
defaultsMethodWithSortAndDirection = SampleController.class.getMethod("defaultsMethodWithSortAndDirection",
|
||||
Pageable.class);
|
||||
|
||||
request = new MockHttpServletRequest();
|
||||
|
||||
// Add pagination info for foo table
|
||||
request.addParameter("foo_page.size", "50");
|
||||
request.addParameter("foo_page.sort", "foo");
|
||||
request.addParameter("foo_page.sort.dir", "asc");
|
||||
|
||||
// Add pagination info for bar table
|
||||
request.addParameter("bar_page.size", "60");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testname() throws Exception {
|
||||
|
||||
assertSizeForPrefix(50, new Sort(Direction.ASC, "foo"), 0);
|
||||
assertSizeForPrefix(60, null, 1);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void rejectsInvalidlyMappedPageables() throws Exception {
|
||||
|
||||
MethodParameter parameter = new MethodParameter(failedMethod, 0);
|
||||
NativeWebRequest webRequest = new ServletWebRequest(request);
|
||||
|
||||
new PageableArgumentResolver().resolveArgument(parameter, webRequest);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void rejectsInvalidQualifiers() throws Exception {
|
||||
|
||||
MethodParameter parameter = new MethodParameter(invalidQualifiers, 0);
|
||||
NativeWebRequest webRequest = new ServletWebRequest(request);
|
||||
|
||||
new PageableArgumentResolver().resolveArgument(parameter, webRequest);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertDefaults() throws Exception {
|
||||
|
||||
Object argument = setupAndResolve(defaultsMethod);
|
||||
|
||||
assertThat(argument, is(instanceOf(Pageable.class)));
|
||||
|
||||
Pageable pageable = (Pageable) argument;
|
||||
assertThat(pageable.getPageSize(), is(SampleController.DEFAULT_PAGESIZE));
|
||||
assertThat(pageable.getPageNumber(), is(SampleController.DEFAULT_PAGENUMBER));
|
||||
assertThat(pageable.getSort(), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertOverridesDefaults() throws Exception {
|
||||
|
||||
Integer sizeParam = 5;
|
||||
|
||||
MethodParameter parameter = new MethodParameter(defaultsMethod, 0);
|
||||
MockHttpServletRequest mockRequest = new MockHttpServletRequest();
|
||||
|
||||
mockRequest.addParameter("page.page", sizeParam.toString());
|
||||
NativeWebRequest webRequest = new ServletWebRequest(mockRequest);
|
||||
PageableArgumentResolver resolver = new PageableArgumentResolver();
|
||||
Object argument = resolver.resolveArgument(parameter, webRequest);
|
||||
|
||||
assertTrue(argument instanceof Pageable);
|
||||
|
||||
Pageable pageable = (Pageable) argument;
|
||||
assertEquals(SampleController.DEFAULT_PAGESIZE, pageable.getPageSize());
|
||||
assertEquals(sizeParam - 1, pageable.getPageNumber());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-146
|
||||
*/
|
||||
@Test
|
||||
public void appliesDefaultSort() {
|
||||
|
||||
Object argument = setupAndResolve(defaultsMethodWithSort);
|
||||
|
||||
assertThat(argument, is(instanceOf(Pageable.class)));
|
||||
|
||||
Pageable pageable = (Pageable) argument;
|
||||
assertThat(pageable.getPageSize(), is(SampleController.DEFAULT_PAGESIZE));
|
||||
assertThat(pageable.getPageNumber(), is(SampleController.DEFAULT_PAGENUMBER));
|
||||
assertThat(pageable.getSort(), is(new Sort("foo")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-146
|
||||
*/
|
||||
@Test
|
||||
public void appliesDefaultSortAndDirection() {
|
||||
|
||||
Object argument = setupAndResolve(defaultsMethodWithSortAndDirection);
|
||||
|
||||
assertThat(argument, is(instanceOf(Pageable.class)));
|
||||
|
||||
Pageable pageable = (Pageable) argument;
|
||||
assertThat(pageable.getPageSize(), is(SampleController.DEFAULT_PAGESIZE));
|
||||
assertThat(pageable.getPageNumber(), is(SampleController.DEFAULT_PAGENUMBER));
|
||||
assertThat(pageable.getSort(), is(new Sort(Direction.DESC, "foo")));
|
||||
}
|
||||
|
||||
private void assertSizeForPrefix(int size, Sort sort, int index) throws Exception {
|
||||
|
||||
MethodParameter parameter = new MethodParameter(correctMethod, index);
|
||||
NativeWebRequest webRequest = new ServletWebRequest(request);
|
||||
|
||||
PageableArgumentResolver resolver = new PageableArgumentResolver();
|
||||
|
||||
Object argument = resolver.resolveArgument(parameter, webRequest);
|
||||
assertThat(argument, is(instanceOf(Pageable.class)));
|
||||
|
||||
Pageable pageable = (Pageable) argument;
|
||||
assertThat(pageable.getPageSize(), is(size));
|
||||
|
||||
if (null != sort) {
|
||||
assertThat(pageable.getSort(), is(sort));
|
||||
}
|
||||
}
|
||||
|
||||
private Object setupAndResolve(Method method) {
|
||||
|
||||
MethodParameter parameter = new MethodParameter(method, 0);
|
||||
NativeWebRequest webRequest = new ServletWebRequest(new MockHttpServletRequest());
|
||||
PageableArgumentResolver resolver = new PageableArgumentResolver();
|
||||
return resolver.resolveArgument(parameter, webRequest);
|
||||
}
|
||||
|
||||
static class SampleController {
|
||||
|
||||
static final int DEFAULT_PAGESIZE = 198;
|
||||
static final int DEFAULT_PAGENUMBER = 42;
|
||||
|
||||
public void defaultsMethod(
|
||||
@PageableDefaults(value = DEFAULT_PAGESIZE, pageNumber = DEFAULT_PAGENUMBER) Pageable pageable) {
|
||||
|
||||
}
|
||||
|
||||
public void defaultsMethodWithSort(
|
||||
@PageableDefaults(value = DEFAULT_PAGESIZE, pageNumber = DEFAULT_PAGENUMBER, sort = "foo") Pageable pageable) {
|
||||
|
||||
}
|
||||
|
||||
public void defaultsMethodWithSortAndDirection(
|
||||
@PageableDefaults(value = DEFAULT_PAGESIZE, pageNumber = DEFAULT_PAGENUMBER, sort = "foo", sortDir = Direction.DESC) Pageable pageable) {
|
||||
|
||||
}
|
||||
|
||||
public void correctMethod(@Qualifier("foo") Pageable first, @Qualifier("bar") Pageable second) {
|
||||
|
||||
}
|
||||
|
||||
public void noQualifiers(Pageable first, Pageable second) {
|
||||
|
||||
}
|
||||
|
||||
public void invalidQualifiers(@Qualifier("foo") Pageable first, @Qualifier("foo") Pageable second) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,6 @@
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm.xsd
|
||||
http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<repository:jackson-populator id="jackson-populator"
|
||||
locations="classpath:org/springframework/data/repository/init/data.json" />
|
||||
|
||||
<repository:jackson2-populator id="jackson2-populator"
|
||||
locations="classpath:org/springframework/data/repository/init/data.json" />
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm.xsd
|
||||
http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<repository:jackson-populator id="jackson-populator"
|
||||
locations="classpath:org/springframework/data/repository/init/data.json" />
|
||||
|
||||
<repository:jackson2-populator id="jackson2-populator"
|
||||
locations="classpath:org/springframework/data/repository/init/data.json" />
|
||||
|
||||
Reference in New Issue
Block a user