diff --git a/src/main/java/org/springframework/data/querydsl/binding/QuerydslBindingsFactory.java b/src/main/java/org/springframework/data/querydsl/binding/QuerydslBindingsFactory.java new file mode 100644 index 000000000..5c8211edf --- /dev/null +++ b/src/main/java/org/springframework/data/querydsl/binding/QuerydslBindingsFactory.java @@ -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, 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, 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 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> findCustomizerForDomainType( + Class 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>) 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> createQuerydslBinderCustomizer( + Class 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> { + + INSTANCE; + + @Override + public void customize(QuerydslBindings bindings, EntityPath root) {} + } +} diff --git a/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java b/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java index f3bc93c1c..a8c201686 100644 --- a/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java +++ b/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java @@ -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 { @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); } /* diff --git a/src/main/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolver.java b/src/main/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolver.java index 82687a7b3..1287f28ae 100644 --- a/src/main/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolver.java +++ b/src/main/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolver.java @@ -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; 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; * @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, 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, 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 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> findCustomizerForDomainType(QuerydslPredicate annotation, - Class domainType) { - - if (annotation != null) { - - Class 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>) 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> createQuerydslBinderCustomizer( - Class 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 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 return detectDomainType(source.getComponentType()); } - - private static enum NoOpCustomizer implements QuerydslBinderCustomizer> { - - INSTANCE; - - @Override - public void customize(QuerydslBindings bindings, EntityPath root) {} - } } diff --git a/src/test/java/org/springframework/data/querydsl/binding/QuerydslBindingsFactoryUnitTests.java b/src/test/java/org/springframework/data/querydsl/binding/QuerydslBindingsFactoryUnitTests.java new file mode 100644 index 000000000..5912ddd93 --- /dev/null +++ b/src/test/java/org/springframework/data/querydsl/binding/QuerydslBindingsFactoryUnitTests.java @@ -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, 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, 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 { + + public void customize(QuerydslBindings bindings, QUser user) { + + bindings.bind(user.firstname).first(new SingleValueBinding() { + + @Override + public Predicate bind(StringPath path, String value) { + return path.eq(value.toUpperCase()); + } + }); + + bindings.bind(user.lastname).first(new SingleValueBinding() { + + @Override + public Predicate bind(StringPath path, String value) { + return path.toLowerCase().eq(value); + } + }); + + bindings.excluding(user.address); + } + } + + public static class SampleRepo implements QuerydslBinderCustomizer { + + @Override + public void customize(QuerydslBindings bindings, QUser user) { + + bindings.bind(QUser.user.firstname).first(new SingleValueBinding() { + + @Override + public Predicate bind(StringPath path, String value) { + return path.contains(value); + } + }); + } + } +} diff --git a/src/test/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolverUnitTests.java b/src/test/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolverUnitTests.java index b829af7a3..bf0b8fa82 100644 --- a/src/test/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolverUnitTests.java +++ b/src/test/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolverUnitTests.java @@ -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, 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, 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 {