Skip to content

Commit 0e36b43

Browse files
committed
DATACMNS-1026 - Polishing.
Minor refactorings here in there for clarity. Original pull request: #217.
1 parent 1bf318f commit 0e36b43

File tree

5 files changed

+37
-30
lines changed

5 files changed

+37
-30
lines changed

src/main/java/org/springframework/data/repository/query/EvaluationContextExtensionInformation.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package org.springframework.data.repository.query;
1717

18+
import static org.springframework.data.util.StreamUtils.*;
19+
1820
import lombok.Getter;
1921
import lombok.RequiredArgsConstructor;
2022

@@ -35,10 +37,10 @@
3537
import org.springframework.data.repository.query.Functions.NameAndArgumentCount;
3638
import org.springframework.data.repository.query.spi.EvaluationContextExtension;
3739
import org.springframework.data.repository.query.spi.Function;
38-
import org.springframework.data.util.MultiValueMapCollector;
3940
import org.springframework.data.util.Streamable;
4041
import org.springframework.util.Assert;
4142
import org.springframework.util.CollectionUtils;
43+
import org.springframework.util.LinkedMultiValueMap;
4244
import org.springframework.util.MultiValueMap;
4345
import org.springframework.util.ReflectionUtils;
4446
import org.springframework.util.ReflectionUtils.FieldFilter;
@@ -55,6 +57,7 @@
5557
*
5658
* @author Oliver Gierke
5759
* @author Christoph Strobl
60+
* @author Jens Schauder
5861
* @since 1.9
5962
*/
6063
class EvaluationContextExtensionInformation {
@@ -248,14 +251,11 @@ public RootObjectInformation(Class<?> type) {
248251
* @return the methods
249252
*/
250253
public MultiValueMap<NameAndArgumentCount, Function> getFunctions(Optional<Object> target) {
254+
return target.map(this::getFunctions).orElseGet(() -> new LinkedMultiValueMap<>());
255+
}
251256

252-
return target.map( //
253-
it -> methods.stream().collect( //
254-
new MultiValueMapCollector<>( //
255-
m -> NameAndArgumentCount.of(m), //
256-
m -> new Function(m, it) //
257-
))) //
258-
.orElseGet(() -> CollectionUtils.toMultiValueMap(Collections.emptyMap()));
257+
private MultiValueMap<NameAndArgumentCount, Function> getFunctions(Object target) {
258+
return methods.stream().collect(toMultiMap(NameAndArgumentCount::of, m -> new Function(m, target)));
259259
}
260260

261261
/**

src/main/java/org/springframework/data/repository/query/Functions.java

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
*/
1616
package org.springframework.data.repository.query;
1717

18+
import lombok.AccessLevel;
1819
import lombok.AllArgsConstructor;
1920
import lombok.Value;
2021

2122
import java.lang.reflect.Method;
2223
import java.util.Collections;
23-
import java.util.HashMap;
2424
import java.util.List;
2525
import java.util.Map;
2626
import java.util.Optional;
@@ -29,7 +29,7 @@
2929

3030
import org.springframework.core.convert.TypeDescriptor;
3131
import org.springframework.data.repository.query.spi.Function;
32-
import org.springframework.util.CollectionUtils;
32+
import org.springframework.util.LinkedMultiValueMap;
3333
import org.springframework.util.MultiValueMap;
3434

3535
/**
@@ -38,18 +38,23 @@
3838
* value lists are actually unique with respect to the signature.
3939
*
4040
* @author Jens Schauder
41+
* @author Oliver Gierke
4142
* @since 2.0
4243
*/
4344
class Functions {
4445

45-
private final MultiValueMap<NameAndArgumentCount, Function> functions = CollectionUtils
46-
.toMultiValueMap(new HashMap<>());
46+
private static final String MESSAGE_TEMPLATE = "There are multiple matching methods of name '%s' for parameter types (%s), but no "
47+
+ "exact match. Make sure to provide only one matching overload or one with exactly those types.";
48+
49+
private final MultiValueMap<NameAndArgumentCount, Function> functions = new LinkedMultiValueMap<>();
4750

4851
void addAll(Map<String, Function> newFunctions) {
4952

5053
newFunctions.forEach((n, f) -> {
51-
NameAndArgumentCount k = new NameAndArgumentCount(n, f.getParameterCount());
54+
55+
NameAndArgumentCount k = NameAndArgumentCount.of(n, f.getParameterCount());
5256
List<Function> currentElements = get(k);
57+
5358
if (!contains(currentElements, f)) {
5459
functions.add(k, f);
5560
}
@@ -59,7 +64,9 @@ void addAll(Map<String, Function> newFunctions) {
5964
void addAll(MultiValueMap<NameAndArgumentCount, Function> newFunctions) {
6065

6166
newFunctions.forEach((k, list) -> {
67+
6268
List<Function> currentElements = get(k);
69+
6370
list.stream() //
6471
.filter(f -> !contains(currentElements, f)) //
6572
.forEach(f -> functions.add(k, f));
@@ -82,7 +89,7 @@ List<Function> get(NameAndArgumentCount key) {
8289
*/
8390
Optional<Function> get(String name, List<TypeDescriptor> argumentTypes) {
8491

85-
Stream<Function> candidates = get(new NameAndArgumentCount(name, argumentTypes.size())).stream() //
92+
Stream<Function> candidates = get(NameAndArgumentCount.of(name, argumentTypes.size())).stream() //
8693
.filter(f -> f.supports(argumentTypes));
8794
return bestMatch(candidates.collect(Collectors.toList()), argumentTypes);
8895
}
@@ -96,11 +103,13 @@ private static Optional<Function> bestMatch(List<Function> candidates, List<Type
96103
if (candidates.isEmpty()) {
97104
return Optional.empty();
98105
}
106+
99107
if (candidates.size() == 1) {
100108
return Optional.of(candidates.get(0));
101109
}
102110

103111
Optional<Function> exactMatch = candidates.stream().filter(f -> f.supportsExact(argumentTypes)).findFirst();
112+
104113
if (!exactMatch.isPresent()) {
105114
throw new IllegalStateException(createErrorMessage(candidates, argumentTypes));
106115
}
@@ -110,24 +119,22 @@ private static Optional<Function> bestMatch(List<Function> candidates, List<Type
110119

111120
private static String createErrorMessage(List<Function> candidates, List<TypeDescriptor> argumentTypes) {
112121

113-
String argumentTypeString = String.join( //
114-
",", //
115-
argumentTypes.stream().map(TypeDescriptor::getName).collect(Collectors.toList()));
122+
String argumentTypeString = argumentTypes.stream()//
123+
.map(TypeDescriptor::getName)//
124+
.collect(Collectors.joining(","));
116125

117-
String messageTemplate = "There are multiple matching methods of name '%s' for parameter types (%s), but no "
118-
+ "exact match. Make sure to provide only one matching overload or one with exactly those types.";
119-
120-
return String.format(messageTemplate, candidates.get(0).getName(), argumentTypeString);
126+
return String.format(MESSAGE_TEMPLATE, candidates.get(0).getName(), argumentTypeString);
121127
}
122128

123129
@Value
124-
@AllArgsConstructor
130+
@AllArgsConstructor(access = AccessLevel.PRIVATE, staticName = "of")
125131
static class NameAndArgumentCount {
132+
126133
String name;
127134
int count;
128135

129136
static NameAndArgumentCount of(Method m) {
130-
return new NameAndArgumentCount(m.getName(), m.getParameterCount());
137+
return NameAndArgumentCount.of(m.getName(), m.getParameterCount());
131138
}
132139
}
133140
}

src/main/java/org/springframework/data/util/MultiValueMapCollector.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.data.util;
1717

18+
import lombok.AccessLevel;
1819
import lombok.NonNull;
1920
import lombok.RequiredArgsConstructor;
2021

@@ -36,11 +37,11 @@
3637
* @author Jens Schauder
3738
* @since 2.0
3839
*/
39-
@RequiredArgsConstructor
40-
public class MultiValueMapCollector<T, K, V> implements Collector<T, MultiValueMap<K, V>, MultiValueMap<K, V>> {
40+
@RequiredArgsConstructor(access = AccessLevel.PACKAGE, staticName = "of")
41+
class MultiValueMapCollector<T, K, V> implements Collector<T, MultiValueMap<K, V>, MultiValueMap<K, V>> {
4142

42-
@NonNull private final Function<T, K> keyFunction;
43-
@NonNull private final Function<T, V> valueFunction;
43+
private final @NonNull Function<T, K> keyFunction;
44+
private final @NonNull Function<T, V> valueFunction;
4445

4546
/*
4647
* (non-Javadoc)

src/main/java/org/springframework/data/util/StreamUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,6 @@ public static <T> Stream<T> createStreamFromIterator(Iterator<T> iterator) {
8888
*/
8989
public static <T, K, V> Collector<T, MultiValueMap<K, V>, MultiValueMap<K, V>> toMultiMap(Function<T, K> keyFunction,
9090
Function<T, V> valueFunction) {
91-
return new MultiValueMapCollector<T, K, V>(keyFunction, valueFunction);
91+
return MultiValueMapCollector.of(keyFunction, valueFunction);
9292
}
9393
}

src/test/java/org/springframework/data/repository/query/ExtensionAwareEvaluationContextProviderUnitTests.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import java.util.Map;
3030
import java.util.concurrent.atomic.AtomicInteger;
3131

32-
import org.assertj.core.api.Assertions;
3332
import org.junit.Before;
3433
import org.junit.Test;
3534
import org.springframework.data.domain.PageRequest;
@@ -273,7 +272,7 @@ public void throwsExceptionWhenStillAmbiguous() throws Exception {
273272
.withMessageContaining("(java.lang.Integer)");
274273
}
275274

276-
private ExtensionAwareEvaluationContextProvider createContextProviderWithOverloads() {
275+
private static ExtensionAwareEvaluationContextProvider createContextProviderWithOverloads() {
277276

278277
return new ExtensionAwareEvaluationContextProvider(Collections.singletonList( //
279278
new DummyExtension("_first", "first") {

0 commit comments

Comments
 (0)