DATACMNS-1026 - ExtensionAwareEvaluationContextProvider now returns all overloaded methods as functions.

All overloaded methods are now available in SPeL expressions. Among methods with identical argument list from different sources in the same extension (extension, root object, aliases) the last one in the order in parens wins. If there is more than one method for an application the following rules are applied: if there is one method with exact matching types in the argument list it is used, otherwise an exception is thrown.

Original pull request: #217.
This commit is contained in:
Jens Schauder
2017-05-04 11:23:04 +02:00
committed by Oliver Gierke
parent 5dba2f4c59
commit 42621086fe
8 changed files with 440 additions and 30 deletions

View File

@@ -0,0 +1,97 @@
/*
* Copyright 2017 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.util;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
/**
* A {@link Collector} for building a {@link MultiValueMap} from a {@link java.util.stream.Stream}.
*
* @author Jens Schauder
* @since 2.0
*/
@RequiredArgsConstructor
public 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;
/*
* (non-Javadoc)
* @see java.util.stream.Collector#supplier()
*/
@Override
public Supplier<MultiValueMap<K, V>> supplier() {
return () -> CollectionUtils.toMultiValueMap(new HashMap<>());
}
/*
* (non-Javadoc)
* @see java.util.stream.Collector#accumulator()
*/
@Override
public BiConsumer<MultiValueMap<K, V>, T> accumulator() {
return (map, t) -> map.add(keyFunction.apply(t), valueFunction.apply(t));
}
/*
* (non-Javadoc)
* @see java.util.stream.Collector#combiner()
*/
@Override
public BinaryOperator<MultiValueMap<K, V>> combiner() {
return (map1, map2) -> {
for (K key : map2.keySet()) {
map1.addAll(key, map2.get(key));
}
return map1;
};
}
/*
* (non-Javadoc)
* @see java.util.stream.Collector#finisher()
*/
@Override
public Function<MultiValueMap<K, V>, MultiValueMap<K, V>> finisher() {
return Function.identity();
}
/*
* (non-Javadoc)
* @see java.util.stream.Collector#characteristics()
*/
@Override
public Set<Characteristics> characteristics() {
return EnumSet.of(Characteristics.IDENTITY_FINISH, Characteristics.UNORDERED);
}
}

View File

@@ -23,11 +23,13 @@ import java.util.List;
import java.util.Set;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.springframework.util.Assert;
import org.springframework.util.MultiValueMap;
/**
* Spring Data specific Java {@link Stream} utility methods and classes.
@@ -77,4 +79,15 @@ public interface StreamUtils {
public static <T> Collector<T, ?, Set<T>> toUnmodifiableSet() {
return collectingAndThen(toSet(), Collections::unmodifiableSet);
}
/**
* Returns a {@link Collector} to create a {@link MultiValueMap}.
*
* @param keyFunction {@link Function} to create a key from an element of the {@link java.util.stream.Stream}
* @param valueFunction {@link Function} to create a value from an element of the {@link java.util.stream.Stream}
*/
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);
}
}