-
Notifications
You must be signed in to change notification settings - Fork 41.2k
Add PropertyMapper.to(...) API designed for immutable instances #31323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
...ct/spring-boot/src/main/java/org/springframework/boot/context/properties/PropertyMapper.java
Outdated
Show resolved
Hide resolved
I wonder if we should have something like someTarget = PropertyMapper.get().from(someProps::foo).whenNonNull().toOptionalInstance(someTarget::updateFoo).orElse(someTarget); |
Absolutely! This gets us out of the "picking what to do in the case it is filtered value" business. No need to pass in default etc.. I will amend the PR shortly. |
...ct/spring-boot/src/main/java/org/springframework/boot/context/properties/PropertyMapper.java
Outdated
Show resolved
Hide resolved
7343a18
to
6a9ed80
Compare
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>
Thanks for all the reviews. After a bit more discussion with @snicoll we decided to circle back to almost the original proposal. Rather than adding a SenderOptions<K, V> senderOptions = SenderOptions.create(this.kafkaProperties.buildReactorProducerProperties());
KafkaProperties.Reactor.Sender senderProperties = this.kafkaProperties.getReactor().getSender();
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
senderOptions = map.from(senderProperties::getCloseTimeout).to(senderOptions, SenderOptions::closeTimeout);
senderOptions = map.from(senderProperties::getMaxInFlight).to(senderOptions, SenderOptions::maxInFlight);
senderOptions = map.from(senderProperties::isStopOnError).to(senderOptions, SenderOptions::stopOnError);
return senderOptions; |
Overview
This proposal adds an API to
PropertyMapper.isInstance
that returns a user-specified default instance when the mapped value has been filtered. The current behavior is to throw an exception when the mapped value has been filtered.Motivation
Some target objects are immutable and return a new instance w/ the mapped value rather than updating the value on the target instance. Consider the following example:
And suppose we have some config prop for "foo" and we want to update the target object's "foo" w/ that value. Typically we would use something like:
However,
Source.to()
does not work in the immutable case becauseupdateFoo
returns the new updated instance. Ok, lets instead useSource.toInstance()
such as:This works fine when the value is not filtered. However, if we add some constraints on the mapper such as:
throws a
NoSuchElementException
whensomeProps::foo
is null. This results in having to test the filter predicate manually prior to callingtoInstance
.Proposed Solution
Allow the caller to pass in a default instance to use when the value is filtered (rather than throw exception). Something like this:
You can see where I have worked around this in https://github.com/spring-projects/spring-boot/pull/31258/files#diff-7f2cc68fbde121f72bcff98a44dc29738be96efb911ffc54b80b6a6dd334b5ccR60