FluentBuilder<D> as interface with default method

This commit is contained in:
Michael Hoennig 2019-04-29 12:19:34 +02:00
parent 1916347490
commit cc0857e33b
5 changed files with 52 additions and 20 deletions

View File

@ -14,7 +14,7 @@ import java.util.Objects;
/**
* A DTO for the Customer entity.
*/
public class CustomerDTO extends FluentBuilder<CustomerDTO> implements AccessMappings {
public class CustomerDTO implements AccessMappings, FluentBuilder<CustomerDTO> {
@SelfId(resolver = CustomerService.class)
@AccessFor(read = Role.ANY_CUSTOMER_USER)

View File

@ -2,10 +2,41 @@ package org.hostsharing.hsadminng.service.dto;
import java.util.function.Consumer;
public class FluentBuilder<T> {
/**
* Just 'implement' this interface in your class to get a pseudo fluent builder, no more code needed.
*
* @param <T> class to be build (same as to which the interface was added)
*/
public interface FluentBuilder<T> {
/**
* Allows statements on the target instance possible as expression.
*
* This allows creating nested object structures, e.g. for test data
* in a much more readable way.
*
* <h3>Example</h3>
* {code
* // adding a fluent builder to your class
* class YourClass implements FluentBuilder<YourClass> {
* public int someField;
* public String anotherField;
* // ...
* }
*
* // using the fluent builder somewhere else
* someMethod( new YourClass().with( it -> {
* it.someField = 5;
* it.anotherField = "Hello";
* }));
* }
*
* @param builderFunction statements to apply to 'this'
*
* @return the instance on which 'with(...)' was executed.
*/
@SuppressWarnings("unchecked")
public T with(
default T with(
Consumer<T> builderFunction) {
builderFunction.accept((T) this);
return (T) this;

View File

@ -8,14 +8,13 @@ import org.springframework.context.ApplicationContext;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.Objects;
/**
* A DTO for the Membership entity.
*/
public class MembershipDTO extends FluentBuilder<MembershipDTO> implements Serializable, AccessMappings {
public class MembershipDTO implements AccessMappings, FluentBuilder<MembershipDTO> {
@SelfId(resolver = MembershipService.class)
@AccessFor(read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})

View File

@ -31,7 +31,7 @@ public class JSonAccessFilterTestFixture {
return dto;
}
static class GivenCustomerDto extends FluentBuilder<GivenCustomerDto> {
static class GivenCustomerDto implements FluentBuilder<GivenCustomerDto> {
@SelfId(resolver = GivenService.class)
@AccessFor(read = ANYBODY)
Long id;
@ -44,7 +44,7 @@ public class JSonAccessFilterTestFixture {
static abstract class GivenCustomerService implements IdToDtoResolver<GivenCustomerDto> {
}
static class GivenDto extends FluentBuilder<GivenDto> {
static class GivenDto implements FluentBuilder<GivenDto> {
@SelfId(resolver = GivenService.class)
@AccessFor(read = ANYBODY)
Long id;
@ -109,7 +109,7 @@ public class JSonAccessFilterTestFixture {
static abstract class GivenChildService implements IdToDtoResolver<GivenChildDto> {
}
public static class GivenChildDto extends FluentBuilder<GivenChildDto> {
public static class GivenChildDto implements FluentBuilder<GivenChildDto> {
@SelfId(resolver = GivenChildService.class)
@AccessFor(read = Role.ANY_CUSTOMER_USER)

View File

@ -73,18 +73,20 @@ public class JSonDeserializationWithAccessFilterUnitTest {
given(ctx.getAutowireCapableBeanFactory()).willReturn(autowireCapableBeanFactory);
given(autowireCapableBeanFactory.createBean(GivenService.class)).willReturn(givenService);
given(givenService.findOne(1234L)).willReturn(Optional.of(new GivenDto()
.with(dto -> dto.id = 1234L)
.with(dto -> dto.customerId = 888L)
.with(dto -> dto.openIntegerField = 11111)
.with(dto -> dto.openPrimitiveIntField = 2222)
.with(dto -> dto.openLongField = 33333333333333L)
.with(dto -> dto.openPrimitiveLongField = 44444444L)
.with(dto -> dto.openBooleanField = true)
.with(dto -> dto.openPrimitiveBooleanField = false)
.with(dto -> dto.openBigDecimalField = SOME_BIG_DECIMAL)
.with(dto -> dto.openStringField = "3333")
.with(dto -> dto.restrictedField = "initial value of restricted field")
.with(dto -> dto.restrictedBigDecimalField = SOME_BIG_DECIMAL)
.with( dto -> {
dto.id = 1234L;
dto.customerId = 888L;
dto.openIntegerField = 11111;
dto.openPrimitiveIntField = 2222;
dto.openLongField = 33333333333333L;
dto.openPrimitiveLongField = 44444444L;
dto.openBooleanField = true;
dto.openPrimitiveBooleanField = false;
dto.openBigDecimalField = SOME_BIG_DECIMAL;
dto.openStringField = "3333";
dto.restrictedField = "initial value of restricted field";
dto.restrictedBigDecimalField = SOME_BIG_DECIMAL;
})
));
given(autowireCapableBeanFactory.createBean(GivenCustomerService.class)).willReturn(givenCustomerService);
given(givenCustomerService.findOne(888L)).willReturn(Optional.of(new GivenCustomerDto()