DATACMNS-669 - Polishing.

Javadoc on MultiValueBinding. Hide QuerydslBindings.bind(…), ….include(…) and ….exclude(…) methods that take String arguments to reduce the probability of no query class being present.

Refined the value handling for empty request values which are represented as String[] containing an empty String. We now massage those into an empty Collection for MultiValueBindings and a null value for SingleValueInvocations.

We currently skip property values that match this pattern entirely but are prepared to allow a configuration flip switch to handle those scenarios in the future. We currently stick to skipping those values to prevent the bindings from having to deal with null values.

We now also allow the bindings to return null to indicate they don't want to get applied in the resulting predicate at all.

Switched to interface based customization to make it easier to use customizations with Spring Data REST. Added Querydsl-specific adapter of RepositoryInvoker to allow Spring Data REST to hook in the execution of the predicate obtained from request parameters.

Original pull request: #132.
This commit is contained in:
Oliver Gierke
2015-07-15 16:13:10 +02:00
parent dc49101850
commit cccfa5e5c5
14 changed files with 506 additions and 136 deletions

View File

@@ -0,0 +1,160 @@
/*
* 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;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Map;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.support.RepositoryInvoker;
import org.springframework.util.Assert;
import org.springframework.util.MultiValueMap;
import com.mysema.query.types.Predicate;
/**
* {@link RepositoryInvoker} that is aware of a {@link QueryDslPredicateExecutor} and {@link Predicate} to be executed
* for all flavors of {@code findAll(…)}. All other calls are forwarded to the configured delegate.
*
* @author Oliver Gierke
*/
public class QuerydslRepositoryInvokerAdapter implements RepositoryInvoker {
private final RepositoryInvoker delegate;
private final QueryDslPredicateExecutor<Object> executor;
private final Predicate predicate;
/**
* Creates a new {@link QuerydslRepositoryInvokerAdapter} for the given delegate {@link RepositoryInvoker},
* {@link QueryDslPredicateExecutor} and Querydsl {@link Predicate}.
*
* @param delegate must not be {@literal null}.
* @param executor must not be {@literal null}.
* @param predicate can be {@literal null}.
*/
public QuerydslRepositoryInvokerAdapter(RepositoryInvoker delegate, QueryDslPredicateExecutor<Object> executor,
Predicate predicate) {
Assert.notNull(delegate, "Delegate RepositoryInvoker must not be null!");
Assert.notNull(executor, "QuerydslPredicateExecutor must not be null!");
this.delegate = delegate;
this.executor = executor;
this.predicate = predicate;
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.support.RepositoryInvoker#invokeFindAll(org.springframework.data.domain.Pageable)
*/
@Override
public Iterable<Object> invokeFindAll(Pageable pageable) {
return executor.findAll(predicate, pageable);
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.support.RepositoryInvoker#invokeFindAll(org.springframework.data.domain.Sort)
*/
@Override
public Iterable<Object> invokeFindAll(Sort sort) {
return executor.findAll(predicate, sort);
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.support.RepositoryInvocationInformation#hasDeleteMethod()
*/
@Override
public boolean hasDeleteMethod() {
return delegate.hasDeleteMethod();
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.support.RepositoryInvocationInformation#hasFindAllMethod()
*/
@Override
public boolean hasFindAllMethod() {
return delegate.hasFindAllMethod();
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.support.RepositoryInvocationInformation#hasFindOneMethod()
*/
@Override
public boolean hasFindOneMethod() {
return delegate.hasFindOneMethod();
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.support.RepositoryInvocationInformation#hasSaveMethod()
*/
@Override
public boolean hasSaveMethod() {
return delegate.hasSaveMethod();
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.support.RepositoryInvoker#invokeDelete(java.io.Serializable)
*/
@Override
public void invokeDelete(Serializable id) {
delegate.invokeDelete(id);
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.support.RepositoryInvoker#invokeFindOne(java.io.Serializable)
*/
@Override
public <T> T invokeFindOne(Serializable id) {
return delegate.invokeFindOne(id);
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.support.RepositoryInvoker#invokeQueryMethod(java.lang.reflect.Method, java.util.Map, org.springframework.data.domain.Pageable, org.springframework.data.domain.Sort)
*/
@Override
public Object invokeQueryMethod(Method method, Map<String, String[]> parameters, Pageable pageable, Sort sort) {
return delegate.invokeQueryMethod(method, parameters, pageable, sort);
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.support.RepositoryInvoker#invokeQueryMethod(java.lang.reflect.Method, org.springframework.util.MultiValueMap, org.springframework.data.domain.Pageable, org.springframework.data.domain.Sort)
*/
@Override
public Object invokeQueryMethod(Method method, MultiValueMap<String, ? extends Object> parameters, Pageable pageable,
Sort sort) {
return delegate.invokeQueryMethod(method, parameters, pageable, sort);
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.support.RepositoryInvoker#invokeSave(java.lang.Object)
*/
@Override
public <T> T invokeSave(T object) {
return delegate.invokeSave(object);
}
}