Browse Source

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.
pull/75/merge
Oliver Gierke 12 years ago
parent
commit
cdc84e45c8
  1. 4
      src/main/java/org/springframework/data/repository/config/ResourceReaderRepositoryPopulatorBeanDefinitionParser.java
  2. 49
      src/main/java/org/springframework/data/repository/init/JacksonRepositoryPopulatorFactoryBean.java
  3. 116
      src/main/java/org/springframework/data/repository/init/JacksonResourceReader.java
  4. 22
      src/main/java/org/springframework/data/web/HateoasPageableHandlerMethodArgumentResolver.java
  5. 20
      src/main/java/org/springframework/data/web/HateoasSortHandlerMethodArgumentResolver.java
  6. 201
      src/main/java/org/springframework/data/web/PageableArgumentResolver.java
  7. 64
      src/main/java/org/springframework/data/web/PageableDefaults.java
  8. 26
      src/main/java/org/springframework/data/web/PageableHandlerMethodArgumentResolver.java
  9. 49
      src/main/java/org/springframework/data/web/SortHandlerMethodArgumentResolver.java
  10. 235
      src/main/resources/org/springframework/data/repository/config/spring-repository-1.8.xsd
  11. 25
      src/test/java/org/springframework/data/repository/config/ResourceReaderRepositoryPopulatorBeanDefinitionParserIntegrationTests.java
  12. 42
      src/test/java/org/springframework/data/repository/init/JacksonResourceReaderIntegrationTests.java
  13. 256
      src/test/java/org/springframework/data/web/LegacyPageableHandlerMethodArgumentResolverUnitTests.java
  14. 218
      src/test/java/org/springframework/data/web/PageableArgumentResolverUnitTests.java
  15. 3
      src/test/resources/org/springframework/data/repository/config/populators-spring-4.0.xml
  16. 3
      src/test/resources/org/springframework/data/repository/config/populators.xml

4
src/main/java/org/springframework/data/repository/config/ResourceReaderRepositoryPopulatorBeanDefinitionParser.java

@ -21,7 +21,6 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder; @@ -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; @@ -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 @@ -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();
}

49
src/main/java/org/springframework/data/repository/init/JacksonRepositoryPopulatorFactoryBean.java

@ -1,49 +0,0 @@ @@ -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);
}
}

116
src/main/java/org/springframework/data/repository/init/JacksonResourceReader.java

@ -1,116 +0,0 @@ @@ -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
src/main/java/org/springframework/data/web/HateoasPageableHandlerMethodArgumentResolver.java

@ -22,7 +22,6 @@ import java.util.Arrays; @@ -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; @@ -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;
/**

20
src/main/java/org/springframework/data/web/HateoasSortHandlerMethodArgumentResolver.java

@ -17,15 +17,12 @@ package org.springframework.data.web; @@ -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 @@ -78,21 +75,10 @@ public class HateoasSortHandlerMethodArgumentResolver extends SortHandlerMethodA
Sort sort = (Sort) value;
String sortParameter = getSortParameter(parameter);
if (legacyMode) {
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);
builder.replaceQueryParam(sortParameter);
for (String expression : foldIntoExpressions(sort)) {
builder.queryParam(sortParameter, expression);
}
for (String expression : foldIntoExpressions(sort)) {
builder.queryParam(sortParameter, expression);
}
}
}

201
src/main/java/org/springframework/data/web/PageableArgumentResolver.java

@ -1,201 +0,0 @@ @@ -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));
}
}
}

64
src/main/java/org/springframework/data/web/PageableDefaults.java

@ -1,64 +0,0 @@ @@ -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;
}

26
src/main/java/org/springframework/data/web/PageableHandlerMethodArgumentResolver.java

@ -1,5 +1,5 @@ @@ -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; @@ -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 @@ -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);
}

49
src/main/java/org/springframework/data/web/SortHandlerMethodArgumentResolver.java

@ -1,5 +1,5 @@ @@ -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; @@ -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 @@ -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 @@ -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 @@ -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 @@ -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;
}

235
src/main/resources/org/springframework/data/repository/config/spring-repository-1.8.xsd

@ -0,0 +1,235 @@ @@ -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>

25
src/test/java/org/springframework/data/repository/config/ResourceReaderRepositoryPopulatorBeanDefinitionParserIntegrationTests.java

@ -1,5 +1,5 @@ @@ -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; @@ -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; @@ -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
*/

42
src/test/java/org/springframework/data/repository/init/JacksonResourceReaderIntegrationTests.java

@ -1,42 +0,0 @@ @@ -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));
}
}

256
src/test/java/org/springframework/data/web/LegacyPageableHandlerMethodArgumentResolverUnitTests.java

@ -1,256 +0,0 @@ @@ -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);
}
}

218
src/test/java/org/springframework/data/web/PageableArgumentResolverUnitTests.java

@ -1,218 +0,0 @@ @@ -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) {
}
}
}

3
src/test/resources/org/springframework/data/repository/config/populators-spring-4.0.xml

@ -5,9 +5,6 @@ @@ -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" />

3
src/test/resources/org/springframework/data/repository/config/populators.xml

@ -5,9 +5,6 @@ @@ -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" />

Loading…
Cancel
Save