1 package com.guinetik.hexafun.hexa;
2
3 import com.guinetik.hexafun.fun.Result;
4 import java.util.ArrayList;
5 import java.util.List;
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 public class UseCaseValidationStep<I> {
21
22 private final String name;
23 private final UseCaseBuilder builder;
24 private final List<ValidationPort<I>> validators;
25
26 public UseCaseValidationStep(
27 String name,
28 UseCaseBuilder builder,
29 ValidationPort<I> validator
30 ) {
31 this.name = name;
32 this.builder = builder;
33 this.validators = new ArrayList<>();
34 this.validators.add(validator);
35 }
36
37 private UseCaseValidationStep(
38 String name,
39 UseCaseBuilder builder,
40 List<ValidationPort<I>> validators
41 ) {
42 this.name = name;
43 this.builder = builder;
44 this.validators = validators;
45 }
46
47
48
49
50
51
52
53
54 public UseCaseValidationStep<I> validate(ValidationPort<I> validator) {
55 List<ValidationPort<I>> newValidators = new ArrayList<>(
56 this.validators
57 );
58 newValidators.add(validator);
59 return new UseCaseValidationStep<>(name, builder, newValidators);
60 }
61
62
63
64
65
66
67
68
69 public <O> UseCaseBuilder handle(UseCase<I, Result<O>> handler) {
70 ValidationPort<I> composedValidator = composeValidators();
71
72 UseCase<I, Result<O>> useCase = input -> {
73 Result<I> validationResult = composedValidator.validate(input);
74 if (validationResult.isFailure()) {
75 return Result.fail(validationResult.error());
76 }
77 return handler.apply(validationResult.get());
78 };
79
80 builder.stage(name, useCase);
81 return builder;
82 }
83
84 private ValidationPort<I> composeValidators() {
85 return input -> {
86 Result<I> result = Result.ok(input);
87 for (ValidationPort<I> validator : validators) {
88 result = result.flatMap(validator::validate);
89 if (result.isFailure()) {
90 return result;
91 }
92 }
93 return result;
94 };
95 }
96 }