Add PropertyMapper.to(...) API designed for immutable instances
Add a new `to` method on `PropertyMapper` designed to work with immutable instances. The new method takes an existing instance and a mapping `BiFunction`. See gh-31323 Co-authored-by: Phillip Webb <pwebb@vmware.com>
This commit is contained in:
parent
e291b8fdcb
commit
8c70acc3c3
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2022 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.
|
||||
|
|
@ -18,6 +18,7 @@ package org.springframework.boot.context.properties;
|
|||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
|
@ -52,6 +53,7 @@ import org.springframework.util.function.SingletonSupplier;
|
|||
*
|
||||
* @author Phillip Webb
|
||||
* @author Artsiom Yudovin
|
||||
* @author Chris Bono
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public final class PropertyMapper {
|
||||
|
|
@ -280,7 +282,7 @@ public final class PropertyMapper {
|
|||
|
||||
/**
|
||||
* Complete the mapping by passing any non-filtered value to the specified
|
||||
* consumer.
|
||||
* consumer. The method is designed to be used with mutable objects.
|
||||
* @param consumer the consumer that should accept the value if it's not been
|
||||
* filtered
|
||||
*/
|
||||
|
|
@ -292,6 +294,24 @@ public final class PropertyMapper {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete the mapping for any non-filtered value by apply the given function to
|
||||
* an existing instance and returning a new one. For filtered values, the
|
||||
* {@code instance} parameter is returned unchanged. The method is designed to be
|
||||
* used with immutable objects.
|
||||
* @param <R> the result type
|
||||
* @param instance the current instance
|
||||
* @param mapper the mapping function
|
||||
* @return a new mapped instance or the original instance
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public <R> R to(R instance, BiFunction<R, T, R> mapper) {
|
||||
Assert.notNull(instance, "Instance must not be null");
|
||||
Assert.notNull(mapper, "Mapper must not be null");
|
||||
T value = this.supplier.get();
|
||||
return (!this.predicate.test(value)) ? instance : mapper.apply(instance, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete the mapping by creating a new instance from the non-filtered value.
|
||||
* @param <R> the resulting type
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2022 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.
|
||||
|
|
@ -29,6 +29,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
|||
*
|
||||
* @author Phillip Webb
|
||||
* @author Artsiom Yudovin
|
||||
* @author Chris Bono
|
||||
*/
|
||||
class PropertyMapperTests {
|
||||
|
||||
|
|
@ -207,6 +208,20 @@ class PropertyMapperTests {
|
|||
assertThat(result).isEqualTo("123");
|
||||
}
|
||||
|
||||
@Test
|
||||
void toImmutableReturnsNewInstance() {
|
||||
Immutable instance = this.map.from("Spring").toInstance(Immutable::of);
|
||||
instance = this.map.from("123").as(Integer::valueOf).to(instance, Immutable::withAge);
|
||||
assertThat(instance).hasToString("Spring 123");
|
||||
}
|
||||
|
||||
@Test
|
||||
void toImmutableWhenFilteredReturnsOriginalInstance() {
|
||||
Immutable instance = this.map.from("Spring").toInstance(Immutable::of);
|
||||
instance = this.map.from("123").when("345"::equals).as(Integer::valueOf).to(instance, Immutable::withAge);
|
||||
assertThat(instance).hasToString("Spring null");
|
||||
}
|
||||
|
||||
static class Count<T> implements Supplier<T> {
|
||||
|
||||
private final Supplier<T> source;
|
||||
|
|
@ -257,4 +272,30 @@ class PropertyMapperTests {
|
|||
|
||||
}
|
||||
|
||||
static class Immutable {
|
||||
|
||||
private final String name;
|
||||
|
||||
private final Integer age;
|
||||
|
||||
Immutable(String name, Integer age) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public Immutable withAge(Integer age) {
|
||||
return new Immutable(this.name, age);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "%s %s".formatted(this.name, this.age);
|
||||
}
|
||||
|
||||
static Immutable of(String name) {
|
||||
return new Immutable(name, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue