DATACMNS-669 - Introduced QuerydslBindingsFactory.
QuerydslBindingsFactory creates a completely build up and customized QuerydslBindings instance for a given QuerydslBinderCustomizer type and domain type. This basically involves creating or obtaining an instance of the customizer with the following algorithm: 1. If an explicit customizer type is given and no BeanFactory is configured, we'll simply instantiate the configured type. This allows simple customizer implementations with a no-arg constructor. 2. If a BeanFactory is configured and a customizer type configured, we're trying to locate a bean of that type in the BeanFactory, falling back to creating an instance of the customizer through the BeanFactory if no existing bean definition can be found. This allows unique customizer bean definitions or complex prototype scoped customizer beans created on the fly. 3. If no customizer type is configured, we check whether the the repository of the domain type implements QuerydslBinderCustomizer and use it if so. The extraction of that functionality allows that algorithm being used by Spring Data REST, although only step 3 is currently used there as no explicit customizer can currently be configured with Spring Data REST.
This commit is contained in:
@@ -17,31 +17,24 @@ package org.springframework.data.web.querydsl;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.data.web.querydsl.QuerydslPredicateArgumentResolver.*;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.mapping.PropertyPath;
|
||||
import org.springframework.data.querydsl.QUser;
|
||||
import org.springframework.data.querydsl.SimpleEntityPathResolver;
|
||||
import org.springframework.data.querydsl.User;
|
||||
import org.springframework.data.querydsl.binding.MultiValueBinding;
|
||||
import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer;
|
||||
import org.springframework.data.querydsl.binding.QuerydslBindings;
|
||||
import org.springframework.data.querydsl.binding.QuerydslBindingsFactory;
|
||||
import org.springframework.data.querydsl.binding.SingleValueBinding;
|
||||
import org.springframework.data.repository.support.Repositories;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.data.web.querydsl.QuerydslPredicate;
|
||||
import org.springframework.data.web.querydsl.QuerydslPredicateArgumentResolver;
|
||||
import org.springframework.hateoas.Resource;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -50,7 +43,6 @@ import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.mysema.query.types.Path;
|
||||
import com.mysema.query.types.Predicate;
|
||||
import com.mysema.query.types.expr.BooleanExpression;
|
||||
import com.mysema.query.types.path.StringPath;
|
||||
@@ -73,7 +65,8 @@ public class QuerydslPredicateArgumentResolverUnitTests {
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
resolver = new QuerydslPredicateArgumentResolver(null);
|
||||
resolver = new QuerydslPredicateArgumentResolver(new QuerydslBindingsFactory(SimpleEntityPathResolver.INSTANCE),
|
||||
null);
|
||||
request = new MockHttpServletRequest();
|
||||
}
|
||||
|
||||
@@ -242,52 +235,6 @@ public class QuerydslPredicateArgumentResolverUnitTests {
|
||||
assertThat(type, is((TypeInformation) ClassTypeInformation.from(User.class)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-669
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void createBindingsShouldHonorQuerydslBinderCustomizerHookWhenPresent() {
|
||||
|
||||
Repositories repositories = mock(Repositories.class);
|
||||
|
||||
when(repositories.hasRepositoryFor(User.class)).thenReturn(true);
|
||||
when(repositories.getRepositoryFor(User.class)).thenReturn(new SampleRepo());
|
||||
|
||||
resolver = new QuerydslPredicateArgumentResolver(null);
|
||||
ReflectionTestUtils.setField(resolver, "repositories", repositories);
|
||||
|
||||
QuerydslBindings bindings = resolver.createBindings(null, USER_TYPE);
|
||||
MultiValueBinding<Path<Object>, Object> binding = bindings
|
||||
.getBindingForPath(PropertyPath.from("firstname", User.class));
|
||||
|
||||
assertThat(binding.bind((Path) QUser.user.firstname, Collections.singleton("rand")),
|
||||
is((Predicate) QUser.user.firstname.contains("rand")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-669
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void shouldReuseExistingQuerydslBinderCustomizer() {
|
||||
|
||||
AutowireCapableBeanFactory beanFactory = mock(AutowireCapableBeanFactory.class);
|
||||
when(beanFactory.getBean(SpecificBinding.class)).thenReturn(new SpecificBinding());
|
||||
QuerydslPredicate annotation = getMethodParameterFor("specificFind", Predicate.class)
|
||||
.getParameterAnnotation(QuerydslPredicate.class);
|
||||
|
||||
resolver = new QuerydslPredicateArgumentResolver(null);
|
||||
ReflectionTestUtils.setField(resolver, "beanFactory", beanFactory);
|
||||
|
||||
QuerydslBindings bindings = resolver.createBindings(annotation, USER_TYPE);
|
||||
MultiValueBinding<Path<Object>, Object> binding = bindings
|
||||
.getBindingForPath(PropertyPath.from("firstname", User.class));
|
||||
|
||||
assertThat(binding.bind((Path) QUser.user.firstname, Collections.singleton("rand")),
|
||||
is((Predicate) QUser.user.firstname.eq("RAND")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-669
|
||||
*/
|
||||
@@ -303,19 +250,6 @@ public class QuerydslPredicateArgumentResolverUnitTests {
|
||||
assertThat(extractTypeInfo(getMethodParameterFor("forModelAndView")), is(MODELA_AND_VIEW_TYPE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-669
|
||||
*/
|
||||
@Test
|
||||
public void rejectsPredicateResolutionIfDomainTypeCantBeAutoDetected() {
|
||||
|
||||
exception.expect(IllegalStateException.class);
|
||||
exception.expectMessage(QuerydslPredicate.class.getSimpleName());
|
||||
exception.expectMessage("root");
|
||||
|
||||
resolver.createBindings(null, ClassTypeInformation.from(ModelAndView.class));
|
||||
}
|
||||
|
||||
private static MethodParameter getMethodParameterFor(String methodName, Class<?>... args) throws RuntimeException {
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user