@ -32,9 +32,11 @@ import org.springframework.core.convert.TypeDescriptor;
@@ -32,9 +32,11 @@ import org.springframework.core.convert.TypeDescriptor;
import org.springframework.data.mapping.PropertyPath ;
import org.springframework.data.querydsl.EntityPathResolver ;
import org.springframework.data.util.TypeInformation ;
import org.springframework.lang.Nullable ;
import org.springframework.util.Assert ;
import org.springframework.util.ClassUtils ;
import org.springframework.util.MultiValueMap ;
import org.springframework.util.String Utils ;
import org.springframework.util.Object Utils ;
import com.querydsl.core.BooleanBuilder ;
import com.querydsl.core.types.Path ;
@ -81,8 +83,7 @@ public class QuerydslPredicateBuilder {
@@ -81,8 +83,7 @@ public class QuerydslPredicateBuilder {
* @param bindings the { @link QuerydslBindings } for the predicate .
* @return the { @link Predicate } .
* /
public Predicate getPredicate ( TypeInformation < ? > type , MultiValueMap < String , String > values ,
QuerydslBindings bindings ) {
public Predicate getPredicate ( TypeInformation < ? > type , MultiValueMap < String , ? > values , QuerydslBindings bindings ) {
Assert . notNull ( bindings , "Context must not be null!" ) ;
@ -92,9 +93,9 @@ public class QuerydslPredicateBuilder {
@@ -92,9 +93,9 @@ public class QuerydslPredicateBuilder {
return getPredicate ( builder ) ;
}
for ( Entry < String , List < String > > entry : values . entrySet ( ) ) {
for ( Entry < String , ? extends List < ? > > entry : values . entrySet ( ) ) {
if ( isSingleElementCollectionWithoutText ( entry . getValue ( ) ) ) {
if ( isSingleElementCollectionWithEmptyItem ( entry . getValue ( ) ) ) {
continue ;
}
@ -165,33 +166,44 @@ public class QuerydslPredicateBuilder {
@@ -165,33 +166,44 @@ public class QuerydslPredicateBuilder {
/ * *
* Converts the given source values into a collection of elements that are of the given { @link PropertyPath } ' s type .
* Considers a single element list with an empty { @link String } an empty collection because this basically indicates
* the property having been submitted but no value provided .
* Considers a single element list with an empty object an empty collection because this basically indicates the
* property having been submitted but no value provided .
*
* @param source must not be { @literal null } .
* @param path must not be { @literal null } .
* @return
* /
private Collection < Object > convertToPropertyPathSpecificType ( List < String > source , PathInformation path ) {
private Collection < Object > convertToPropertyPathSpecificType ( List < ? > source , PathInformation path ) {
Class < ? > targetType = path . getLeafType ( ) ;
if ( source . isEmpty ( ) | | isSingleElementCollectionWithoutText ( source ) ) {
if ( source . isEmpty ( ) | | isSingleElementCollectionWithEmptyItem ( source ) ) {
return Collections . emptyList ( ) ;
}
Collection < Object > target = new ArrayList < > ( source . size ( ) ) ;
for ( String value : source ) {
target . add ( conversionService . canConvert ( String . class , targetType )
? conversionService . convert ( value , TypeDescriptor . forObject ( value ) , getTargetTypeDescriptor ( path ) )
: value ) ;
for ( Object value : source ) {
target . add ( getValue ( path , targetType , value ) ) ;
}
return target ;
}
@Nullable
private Object getValue ( PathInformation path , Class < ? > targetType , Object value ) {
if ( ClassUtils . isAssignableValue ( targetType , value ) ) {
return value ;
}
if ( conversionService . canConvert ( value . getClass ( ) , targetType ) ) {
return conversionService . convert ( value , TypeDescriptor . forObject ( value ) , getTargetTypeDescriptor ( path ) ) ;
}
return value ;
}
/ * *
* Returns the target { @link TypeDescriptor } for the given { @link PathInformation } by either inspecting the field or
* property ( the latter preferred ) to pick up annotations potentially defined for formatting purposes .
@ -213,21 +225,21 @@ public class QuerydslPredicateBuilder {
@@ -213,21 +225,21 @@ public class QuerydslPredicateBuilder {
. nested ( new Property ( owningType , descriptor . getReadMethod ( ) , descriptor . getWriteMethod ( ) , leafProperty ) , 0 ) ;
if ( result = = null ) {
throw new IllegalStateException ( String . format ( "Could not obtain TypeDesciptor for PathInformation %s!" , path ) ) ;
throw new IllegalStateException ( String . format ( "Could not obtain TypeDescr iptor for PathInformation %s!" , path ) ) ;
}
return result ;
}
/ * *
* Returns whether the given collection has exactly one element that doesn ' t contain any text . This is basically an
* indicator that a request parameter has been submitted but no value for it .
* Returns whether the given collection has exactly one element that is empty ( i . e . doesn ' t contain text ) . This is
* basically an indicator that a request parameter has been submitted but no value for it .
*
* @param source must not be { @literal null } .
* @return
* /
private static boolean isSingleElementCollectionWithoutText ( List < String > source ) {
return source . size ( ) = = 1 & & ! StringUtils . hasLength ( source . get ( 0 ) ) ;
private static boolean isSingleElementCollectionWithEmptyItem ( List < ? > source ) {
return source . size ( ) = = 1 & & ObjectUtils . isEmpty ( source . get ( 0 ) ) ;
}
/ * *