Browse Source

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.
pull/136/head
Oliver Gierke 11 years ago
parent
commit
8d2933f109
  1. 176
      src/main/java/org/springframework/data/querydsl/binding/QuerydslBindingsFactory.java
  2. 10
      src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java
  3. 148
      src/main/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolver.java
  4. 158
      src/test/java/org/springframework/data/querydsl/binding/QuerydslBindingsFactoryUnitTests.java
  5. 74
      src/test/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolverUnitTests.java

176
src/main/java/org/springframework/data/querydsl/binding/QuerydslBindingsFactory.java

@ -0,0 +1,176 @@ @@ -0,0 +1,176 @@
/*
* Copyright 2015 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.querydsl.binding;
import java.util.Map;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.querydsl.EntityPathResolver;
import org.springframework.data.repository.support.Repositories;
import org.springframework.data.util.TypeInformation;
import org.springframework.data.web.querydsl.QuerydslPredicate;
import org.springframework.util.Assert;
import org.springframework.util.ConcurrentReferenceHashMap;
import com.mysema.query.types.EntityPath;
/**
* @author Oliver Gierke
*/
public class QuerydslBindingsFactory implements ApplicationContextAware {
private static final String INVALID_DOMAIN_TYPE = "Unable to find Querydsl root type for detected domain type %s! User @%s's root attribute to define the domain type manually!";
private final EntityPathResolver entityPathResolver;
private final Map<TypeInformation<?>, EntityPath<?>> entityPaths;
private AutowireCapableBeanFactory beanFactory;
private Repositories repositories;
/**
* @param entityPathResolver must not be {@literal null}.
*/
public QuerydslBindingsFactory(EntityPathResolver entityPathResolver) {
Assert.notNull(entityPathResolver, "EntityPathResolver must not be null!");
this.entityPathResolver = entityPathResolver;
this.entityPaths = new ConcurrentReferenceHashMap<TypeInformation<?>, EntityPath<?>>();
}
/*
* (non-Javadoc)
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.beanFactory = applicationContext.getAutowireCapableBeanFactory();
this.repositories = new Repositories(applicationContext);
}
/**
* Returns the {@link EntityPathResolver} used by the factory.
*
* @return the entityPathResolver
*/
public EntityPathResolver getEntityPathResolver() {
return entityPathResolver;
}
public QuerydslBindings createBindingsFor(Class<? extends QuerydslBinderCustomizer> customizer,
TypeInformation<?> domainType) {
EntityPath<?> path = verifyEntityPathPresent(domainType);
QuerydslBindings bindings = new QuerydslBindings();
findCustomizerForDomainType(customizer, domainType.getType()).customize(bindings, path);
return bindings;
}
/**
* Tries to detect a Querydsl query type for the given domain type candidate via the configured
* {@link EntityPathResolver}.
*
* @param candidate must not be {@literal null}.
* @throws IllegalStateException to indicate the query type can't be found and manual configuration is necessary.
*/
private EntityPath<?> verifyEntityPathPresent(TypeInformation<?> candidate) {
EntityPath<?> path = entityPaths.get(candidate);
if (path != null) {
return path;
}
Class<?> type = candidate.getType();
try {
path = entityPathResolver.createPath(type);
} catch (IllegalArgumentException o_O) {
throw new IllegalStateException(
String.format(INVALID_DOMAIN_TYPE, candidate.getType(), QuerydslPredicate.class.getSimpleName()), o_O);
}
entityPaths.put(candidate, path);
return path;
}
/**
* Obtains the {@link QuerydslBinderCustomizer} for the given domain type. Will inspect the given annotation for a
* dedicatedly configured one or consider the domain types's repository.
*
* @param annotation
* @param domainType
* @return
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private QuerydslBinderCustomizer<EntityPath<?>> findCustomizerForDomainType(
Class<? extends QuerydslBinderCustomizer> customizer, Class<?> domainType) {
if (customizer != null && !QuerydslBinderCustomizer.class.equals(customizer)) {
return createQuerydslBinderCustomizer(customizer);
}
if (repositories != null && repositories.hasRepositoryFor(domainType)) {
Object repository = repositories.getRepositoryFor(domainType);
if (repository instanceof QuerydslBinderCustomizer) {
return (QuerydslBinderCustomizer<EntityPath<?>>) repository;
}
}
return NoOpCustomizer.INSTANCE;
}
/**
* Obtains a {@link QuerydslBinderCustomizer} for the given type. Will try to obtain a bean from the
* {@link org.springframework.beans.factory.BeanFactory} first or fall back to create a fresh instance through the
* {@link org.springframework.beans.factory.BeanFactory} or finally falling back to a plain instantiation if no
* {@link org.springframework.beans.factory.BeanFactory} is present.
*
* @param type must not be {@literal null}.
* @return
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private QuerydslBinderCustomizer<EntityPath<?>> createQuerydslBinderCustomizer(
Class<? extends QuerydslBinderCustomizer> type) {
if (beanFactory == null) {
return BeanUtils.instantiateClass(type);
}
try {
return beanFactory.getBean(type);
} catch (NoSuchBeanDefinitionException e) {
return beanFactory.createBean(type);
}
}
private static enum NoOpCustomizer implements QuerydslBinderCustomizer<EntityPath<?>> {
INSTANCE;
@Override
public void customize(QuerydslBindings bindings, EntityPath<?> root) {}
}
}

10
src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java

@ -28,6 +28,8 @@ import org.springframework.core.convert.ConversionService; @@ -28,6 +28,8 @@ import org.springframework.core.convert.ConversionService;
import org.springframework.data.geo.format.DistanceFormatter;
import org.springframework.data.geo.format.PointFormatter;
import org.springframework.data.querydsl.QueryDslUtils;
import org.springframework.data.querydsl.SimpleEntityPathResolver;
import org.springframework.data.querydsl.binding.QuerydslBindingsFactory;
import org.springframework.data.repository.support.DomainClassConverter;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.data.web.ProxyingHandlerMethodArgumentResolver;
@ -80,7 +82,13 @@ public class SpringDataWebConfiguration extends WebMvcConfigurerAdapter { @@ -80,7 +82,13 @@ public class SpringDataWebConfiguration extends WebMvcConfigurerAdapter {
@Lazy
@Bean
public HandlerMethodArgumentResolver querydslPredicateArgumentResolver() {
return new QuerydslPredicateArgumentResolver(conversionService.getObject());
return new QuerydslPredicateArgumentResolver(querydslBindingsFactory(), conversionService.getObject());
}
@Lazy
@Bean
public QuerydslBindingsFactory querydslBindingsFactory() {
return new QuerydslBindingsFactory(SimpleEntityPathResolver.INSTANCE);
}
/*

148
src/main/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolver.java

@ -16,27 +16,17 @@ @@ -16,27 +16,17 @@
package org.springframework.data.web.querydsl;
import java.util.Arrays;
import java.util.Map;
import java.util.Map.Entry;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.querydsl.EntityPathResolver;
import org.springframework.data.querydsl.SimpleEntityPathResolver;
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.QuerydslPredicateBuilder;
import org.springframework.data.repository.support.Repositories;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.ConcurrentReferenceHashMap;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.support.WebDataBinderFactory;
@ -44,7 +34,6 @@ import org.springframework.web.context.request.NativeWebRequest; @@ -44,7 +34,6 @@ import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import com.mysema.query.types.EntityPath;
import com.mysema.query.types.Predicate;
/**
@ -55,38 +44,23 @@ import com.mysema.query.types.Predicate; @@ -55,38 +44,23 @@ import com.mysema.query.types.Predicate;
* @author Oliver Gierke
* @since 1.11
*/
public class QuerydslPredicateArgumentResolver implements HandlerMethodArgumentResolver, ApplicationContextAware {
public class QuerydslPredicateArgumentResolver implements HandlerMethodArgumentResolver {
private static final String INVALID_DOMAIN_TYPE = "Unable to find Querydsl root type for detected domain type %s! User @%s's root attribute to define the domain type manually!";
private final QuerydslBindingsFactory bindingsFactory;
private final QuerydslPredicateBuilder predicateBuilder;
private final EntityPathResolver resolver;
private final Map<TypeInformation<?>, EntityPath<?>> entityPaths;
private AutowireCapableBeanFactory beanFactory;
private Repositories repositories;
/**
* Creates a new {@link QuerydslPredicateArgumentResolver} using the given {@link ConversionService}.
*
* @param factory
* @param conversionService defaults to {@link DefaultConversionService} if {@literal null}.
*/
public QuerydslPredicateArgumentResolver(ConversionService conversionService) {
public QuerydslPredicateArgumentResolver(QuerydslBindingsFactory factory, ConversionService conversionService) {
this.resolver = SimpleEntityPathResolver.INSTANCE;
this.entityPaths = new ConcurrentReferenceHashMap<TypeInformation<?>, EntityPath<?>>();
this.bindingsFactory = factory;
this.predicateBuilder = new QuerydslPredicateBuilder(
conversionService == null ? new DefaultConversionService() : conversionService, resolver);
}
/*
* (non-Javadoc)
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.beanFactory = applicationContext.getAutowireCapableBeanFactory();
this.repositories = new Repositories(applicationContext);
conversionService == null ? new DefaultConversionService() : conversionService,
factory.getEntityPathResolver());
}
/*
@ -125,102 +99,10 @@ public class QuerydslPredicateArgumentResolver implements HandlerMethodArgumentR @@ -125,102 +99,10 @@ public class QuerydslPredicateArgumentResolver implements HandlerMethodArgumentR
QuerydslPredicate annotation = parameter.getParameterAnnotation(QuerydslPredicate.class);
TypeInformation<?> domainType = extractTypeInfo(parameter).getActualType();
return predicateBuilder.getPredicate(domainType, parameters, createBindings(annotation, domainType));
}
QuerydslBindings createBindings(QuerydslPredicate annotation, TypeInformation<?> domainType) {
EntityPath<?> path = verifyEntityPathPresent(domainType);
QuerydslBindings bindings = new QuerydslBindings();
findCustomizerForDomainType(annotation, domainType.getType()).customize(bindings, path);
return bindings;
}
/**
* Obtains the {@link QuerydslBinderCustomizer} for the given domain type. Will inspect the given annotation for a
* dedicatedly configured one or consider the domain types's repository.
*
* @param annotation
* @param domainType
* @return
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private QuerydslBinderCustomizer<EntityPath<?>> findCustomizerForDomainType(QuerydslPredicate annotation,
Class<?> domainType) {
if (annotation != null) {
Class<? extends QuerydslBinderCustomizer> bindings = annotation.bindings();
if (bindings != QuerydslBinderCustomizer.class) {
return createQuerydslBinderCustomizer(bindings);
}
}
if (repositories != null && repositories.hasRepositoryFor(domainType)) {
Object repository = repositories.getRepositoryFor(domainType);
if (repository instanceof QuerydslBinderCustomizer) {
return (QuerydslBinderCustomizer<EntityPath<?>>) repository;
}
}
return NoOpCustomizer.INSTANCE;
}
/**
* Obtains a {@link QuerydslBinderCustomizer} for the given type. Will try to obtain a bean from the
* {@link org.springframework.beans.factory.BeanFactory} first or fall back to create a fresh instance through the
* {@link org.springframework.beans.factory.BeanFactory} or finally falling back to a plain instantiation if no
* {@link org.springframework.beans.factory.BeanFactory} is present.
*
* @param type must not be {@literal null}.
* @return
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private QuerydslBinderCustomizer<EntityPath<?>> createQuerydslBinderCustomizer(
Class<? extends QuerydslBinderCustomizer> type) {
if (beanFactory == null) {
return BeanUtils.instantiateClass(type);
}
try {
return beanFactory.getBean(type);
} catch (NoSuchBeanDefinitionException e) {
return beanFactory.createBean(type);
}
}
/**
* Tries to detect a Querydsl query type for the given domain type candidate via the configured
* {@link EntityPathResolver}.
*
* @param candidate must not be {@literal null}.
* @throws IllegalStateException to indicate the query type can't be found and manual configuration is necessary.
*/
private EntityPath<?> verifyEntityPathPresent(TypeInformation<?> candidate) {
EntityPath<?> path = entityPaths.get(candidate);
if (path != null) {
return path;
}
Class<?> type = candidate.getType();
Class<? extends QuerydslBinderCustomizer> customizer = annotation == null ? null : annotation.bindings();
QuerydslBindings bindings = bindingsFactory.createBindingsFor(customizer, domainType);
try {
path = resolver.createPath(type);
} catch (IllegalArgumentException o_O) {
throw new IllegalStateException(
String.format(INVALID_DOMAIN_TYPE, candidate.getType(), QuerydslPredicate.class.getSimpleName()), o_O);
}
entityPaths.put(candidate, path);
return path;
return predicateBuilder.getPredicate(domainType, parameters, bindings);
}
/**
@ -259,12 +141,4 @@ public class QuerydslPredicateArgumentResolver implements HandlerMethodArgumentR @@ -259,12 +141,4 @@ public class QuerydslPredicateArgumentResolver implements HandlerMethodArgumentR
return detectDomainType(source.getComponentType());
}
private static enum NoOpCustomizer implements QuerydslBinderCustomizer<EntityPath<?>> {
INSTANCE;
@Override
public void customize(QuerydslBindings bindings, EntityPath<?> root) {}
}
}

158
src/test/java/org/springframework/data/querydsl/binding/QuerydslBindingsFactoryUnitTests.java

@ -0,0 +1,158 @@ @@ -0,0 +1,158 @@
/*
* Copyright 2015 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.querydsl.binding;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
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.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.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.test.util.ReflectionTestUtils;
import org.springframework.web.servlet.ModelAndView;
import com.mysema.query.types.Path;
import com.mysema.query.types.Predicate;
import com.mysema.query.types.path.StringPath;
/**
* Unit tests for {@link QuerydslBindingsFactory}.
*
* @author Oliver Gierke
* @soundtrack Miles Davis - All Blues (Kind of Blue)
*/
public class QuerydslBindingsFactoryUnitTests {
static final TypeInformation<?> USER_TYPE = ClassTypeInformation.from(User.class);
public @Rule ExpectedException exception = ExpectedException.none();
QuerydslBindingsFactory factory;
@Before
public void setUp() {
this.factory = new QuerydslBindingsFactory(SimpleEntityPathResolver.INSTANCE);
}
/**
* @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());
QuerydslBindingsFactory factory = new QuerydslBindingsFactory(SimpleEntityPathResolver.INSTANCE);
ReflectionTestUtils.setField(factory, "repositories", repositories);
QuerydslBindings bindings = factory.createBindingsFor(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());
QuerydslBindingsFactory factory = new QuerydslBindingsFactory(SimpleEntityPathResolver.INSTANCE);
ReflectionTestUtils.setField(factory, "beanFactory", beanFactory);
QuerydslBindings bindings = factory.createBindingsFor(SpecificBinding.class, 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
*/
@Test
public void rejectsPredicateResolutionIfDomainTypeCantBeAutoDetected() {
exception.expect(IllegalStateException.class);
exception.expectMessage(QuerydslPredicate.class.getSimpleName());
exception.expectMessage("root");
factory.createBindingsFor(null, ClassTypeInformation.from(ModelAndView.class));
}
static class SpecificBinding implements QuerydslBinderCustomizer<QUser> {
public void customize(QuerydslBindings bindings, QUser user) {
bindings.bind(user.firstname).first(new SingleValueBinding<StringPath, String>() {
@Override
public Predicate bind(StringPath path, String value) {
return path.eq(value.toUpperCase());
}
});
bindings.bind(user.lastname).first(new SingleValueBinding<StringPath, String>() {
@Override
public Predicate bind(StringPath path, String value) {
return path.toLowerCase().eq(value);
}
});
bindings.excluding(user.address);
}
}
public static class SampleRepo implements QuerydslBinderCustomizer<QUser> {
@Override
public void customize(QuerydslBindings bindings, QUser user) {
bindings.bind(QUser.user.firstname).first(new SingleValueBinding<StringPath, String>() {
@Override
public Predicate bind(StringPath path, String value) {
return path.contains(value);
}
});
}
}
}

74
src/test/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolverUnitTests.java

@ -17,31 +17,24 @@ package org.springframework.data.web.querydsl; @@ -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; @@ -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 { @@ -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 { @@ -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 { @@ -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 {

Loading…
Cancel
Save