DATACMNS-1026 - Polishing.
Minor refactorings here in there for clarity. Original pull request: #217.
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.repository.query;
|
||||
|
||||
import static org.springframework.data.util.StreamUtils.*;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@@ -35,10 +37,10 @@ import org.springframework.data.repository.query.EvaluationContextExtensionInfor
|
||||
import org.springframework.data.repository.query.Functions.NameAndArgumentCount;
|
||||
import org.springframework.data.repository.query.spi.EvaluationContextExtension;
|
||||
import org.springframework.data.repository.query.spi.Function;
|
||||
import org.springframework.data.util.MultiValueMapCollector;
|
||||
import org.springframework.data.util.Streamable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.ReflectionUtils.FieldFilter;
|
||||
@@ -55,6 +57,7 @@ import org.springframework.util.ReflectionUtils.MethodFilter;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
* @author Jens Schauder
|
||||
* @since 1.9
|
||||
*/
|
||||
class EvaluationContextExtensionInformation {
|
||||
@@ -248,14 +251,11 @@ class EvaluationContextExtensionInformation {
|
||||
* @return the methods
|
||||
*/
|
||||
public MultiValueMap<NameAndArgumentCount, Function> getFunctions(Optional<Object> target) {
|
||||
return target.map(this::getFunctions).orElseGet(() -> new LinkedMultiValueMap<>());
|
||||
}
|
||||
|
||||
return target.map( //
|
||||
it -> methods.stream().collect( //
|
||||
new MultiValueMapCollector<>( //
|
||||
m -> NameAndArgumentCount.of(m), //
|
||||
m -> new Function(m, it) //
|
||||
))) //
|
||||
.orElseGet(() -> CollectionUtils.toMultiValueMap(Collections.emptyMap()));
|
||||
private MultiValueMap<NameAndArgumentCount, Function> getFunctions(Object target) {
|
||||
return methods.stream().collect(toMultiMap(NameAndArgumentCount::of, m -> new Function(m, target)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
*/
|
||||
package org.springframework.data.repository.query;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Value;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -29,7 +29,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.data.repository.query.spi.Function;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
/**
|
||||
@@ -38,18 +38,23 @@ import org.springframework.util.MultiValueMap;
|
||||
* value lists are actually unique with respect to the signature.
|
||||
*
|
||||
* @author Jens Schauder
|
||||
* @author Oliver Gierke
|
||||
* @since 2.0
|
||||
*/
|
||||
class Functions {
|
||||
|
||||
private final MultiValueMap<NameAndArgumentCount, Function> functions = CollectionUtils
|
||||
.toMultiValueMap(new HashMap<>());
|
||||
private static final String MESSAGE_TEMPLATE = "There are multiple matching methods of name '%s' for parameter types (%s), but no "
|
||||
+ "exact match. Make sure to provide only one matching overload or one with exactly those types.";
|
||||
|
||||
private final MultiValueMap<NameAndArgumentCount, Function> functions = new LinkedMultiValueMap<>();
|
||||
|
||||
void addAll(Map<String, Function> newFunctions) {
|
||||
|
||||
newFunctions.forEach((n, f) -> {
|
||||
NameAndArgumentCount k = new NameAndArgumentCount(n, f.getParameterCount());
|
||||
|
||||
NameAndArgumentCount k = NameAndArgumentCount.of(n, f.getParameterCount());
|
||||
List<Function> currentElements = get(k);
|
||||
|
||||
if (!contains(currentElements, f)) {
|
||||
functions.add(k, f);
|
||||
}
|
||||
@@ -59,7 +64,9 @@ class Functions {
|
||||
void addAll(MultiValueMap<NameAndArgumentCount, Function> newFunctions) {
|
||||
|
||||
newFunctions.forEach((k, list) -> {
|
||||
|
||||
List<Function> currentElements = get(k);
|
||||
|
||||
list.stream() //
|
||||
.filter(f -> !contains(currentElements, f)) //
|
||||
.forEach(f -> functions.add(k, f));
|
||||
@@ -82,7 +89,7 @@ class Functions {
|
||||
*/
|
||||
Optional<Function> get(String name, List<TypeDescriptor> argumentTypes) {
|
||||
|
||||
Stream<Function> candidates = get(new NameAndArgumentCount(name, argumentTypes.size())).stream() //
|
||||
Stream<Function> candidates = get(NameAndArgumentCount.of(name, argumentTypes.size())).stream() //
|
||||
.filter(f -> f.supports(argumentTypes));
|
||||
return bestMatch(candidates.collect(Collectors.toList()), argumentTypes);
|
||||
}
|
||||
@@ -96,11 +103,13 @@ class Functions {
|
||||
if (candidates.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (candidates.size() == 1) {
|
||||
return Optional.of(candidates.get(0));
|
||||
}
|
||||
|
||||
Optional<Function> exactMatch = candidates.stream().filter(f -> f.supportsExact(argumentTypes)).findFirst();
|
||||
|
||||
if (!exactMatch.isPresent()) {
|
||||
throw new IllegalStateException(createErrorMessage(candidates, argumentTypes));
|
||||
}
|
||||
@@ -110,24 +119,22 @@ class Functions {
|
||||
|
||||
private static String createErrorMessage(List<Function> candidates, List<TypeDescriptor> argumentTypes) {
|
||||
|
||||
String argumentTypeString = String.join( //
|
||||
",", //
|
||||
argumentTypes.stream().map(TypeDescriptor::getName).collect(Collectors.toList()));
|
||||
String argumentTypeString = argumentTypes.stream()//
|
||||
.map(TypeDescriptor::getName)//
|
||||
.collect(Collectors.joining(","));
|
||||
|
||||
String messageTemplate = "There are multiple matching methods of name '%s' for parameter types (%s), but no "
|
||||
+ "exact match. Make sure to provide only one matching overload or one with exactly those types.";
|
||||
|
||||
return String.format(messageTemplate, candidates.get(0).getName(), argumentTypeString);
|
||||
return String.format(MESSAGE_TEMPLATE, candidates.get(0).getName(), argumentTypeString);
|
||||
}
|
||||
|
||||
@Value
|
||||
@AllArgsConstructor
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE, staticName = "of")
|
||||
static class NameAndArgumentCount {
|
||||
|
||||
String name;
|
||||
int count;
|
||||
|
||||
static NameAndArgumentCount of(Method m) {
|
||||
return new NameAndArgumentCount(m.getName(), m.getParameterCount());
|
||||
return NameAndArgumentCount.of(m.getName(), m.getParameterCount());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.util;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@@ -36,11 +37,11 @@ import org.springframework.util.MultiValueMap;
|
||||
* @author Jens Schauder
|
||||
* @since 2.0
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class MultiValueMapCollector<T, K, V> implements Collector<T, MultiValueMap<K, V>, MultiValueMap<K, V>> {
|
||||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE, staticName = "of")
|
||||
class MultiValueMapCollector<T, K, V> implements Collector<T, MultiValueMap<K, V>, MultiValueMap<K, V>> {
|
||||
|
||||
@NonNull private final Function<T, K> keyFunction;
|
||||
@NonNull private final Function<T, V> valueFunction;
|
||||
private final @NonNull Function<T, K> keyFunction;
|
||||
private final @NonNull Function<T, V> valueFunction;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
||||
@@ -88,6 +88,6 @@ public interface StreamUtils {
|
||||
*/
|
||||
public static <T, K, V> Collector<T, MultiValueMap<K, V>, MultiValueMap<K, V>> toMultiMap(Function<T, K> keyFunction,
|
||||
Function<T, V> valueFunction) {
|
||||
return new MultiValueMapCollector<T, K, V>(keyFunction, valueFunction);
|
||||
return MultiValueMapCollector.of(keyFunction, valueFunction);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
@@ -273,7 +272,7 @@ public class ExtensionAwareEvaluationContextProviderUnitTests {
|
||||
.withMessageContaining("(java.lang.Integer)");
|
||||
}
|
||||
|
||||
private ExtensionAwareEvaluationContextProvider createContextProviderWithOverloads() {
|
||||
private static ExtensionAwareEvaluationContextProvider createContextProviderWithOverloads() {
|
||||
|
||||
return new ExtensionAwareEvaluationContextProvider(Collections.singletonList( //
|
||||
new DummyExtension("_first", "first") {
|
||||
|
||||
Reference in New Issue
Block a user