6
6
import java .util .List ;
7
7
import java .util .Map ;
8
8
import java .util .Optional ;
9
+ import java .util .function .BiConsumer ;
9
10
import java .util .function .Consumer ;
10
11
import lombok .RequiredArgsConstructor ;
11
12
import lombok .extern .slf4j .Slf4j ;
13
+ import org .apache .commons .lang3 .tuple .Pair ;
12
14
13
15
@ Slf4j
14
16
@ RequiredArgsConstructor
15
17
@ SuppressWarnings ({"unchecked" , "rawtypes" })
16
18
class HookSupport {
17
19
18
20
public EvaluationContext beforeHooks (
19
- FlagValueType flagValueType , HookContext hookCtx , List <Hook > hooks , Map <String , Object > hints ) {
20
- return callBeforeHooks (flagValueType , hookCtx , hooks , hints );
21
+ FlagValueType flagValueType , HookContext hookCtx , List <Pair < Hook , HookData >> hookDataPairs , Map <String , Object > hints ) {
22
+ return callBeforeHooks (flagValueType , hookCtx , hookDataPairs , hints );
21
23
}
22
24
23
25
public void afterHooks (
24
26
FlagValueType flagValueType ,
25
27
HookContext hookContext ,
26
28
FlagEvaluationDetails details ,
27
- List <Hook > hooks ,
29
+ List <Pair < Hook , HookData >> hookDataPairs ,
28
30
Map <String , Object > hints ) {
29
- executeHooksUnchecked (flagValueType , hooks , hook -> hook .after (hookContext , details , hints ));
31
+ executeHooksUnchecked (flagValueType , hookDataPairs , hookContext , ( hook , ctx ) -> hook .after (ctx , details , hints ));
30
32
}
31
33
32
34
public void afterAllHooks (
33
35
FlagValueType flagValueType ,
34
36
HookContext hookCtx ,
35
37
FlagEvaluationDetails details ,
36
- List <Hook > hooks ,
38
+ List <Pair < Hook , HookData >> hookDataPairs ,
37
39
Map <String , Object > hints ) {
38
- executeHooks (flagValueType , hooks , "finally" , hook -> hook .finallyAfter (hookCtx , details , hints ));
40
+ executeHooks (flagValueType , hookDataPairs , hookCtx , "finally" , ( hook , ctx ) -> hook .finallyAfter (ctx , details , hints ));
39
41
}
40
42
41
43
public void errorHooks (
42
44
FlagValueType flagValueType ,
43
45
HookContext hookCtx ,
44
46
Exception e ,
45
- List <Hook > hooks ,
47
+ List <Pair < Hook , HookData >> hookDataPairs ,
46
48
Map <String , Object > hints ) {
47
- executeHooks (flagValueType , hooks , "error" , hook -> hook .error (hookCtx , e , hints ));
49
+ executeHooks (flagValueType , hookDataPairs , hookCtx , "error" , (hook , ctx ) -> hook .error (ctx , e , hints ));
50
+ }
51
+
52
+ public List <Pair <Hook , HookData >> getHookDataPairs (List <Hook > hooks ) {
53
+ var pairs = new ArrayList <Pair <Hook , HookData >>();
54
+ for (Hook hook : hooks ) {
55
+ pairs .add (Pair .of (hook , HookData .create ()));
56
+ }
57
+ return pairs ;
48
58
}
49
59
50
60
private <T > void executeHooks (
51
- FlagValueType flagValueType , List <Hook > hooks , String hookMethod , Consumer <Hook <T >> hookCode ) {
52
- if (hooks != null ) {
53
- for (Hook hook : hooks ) {
61
+ FlagValueType flagValueType , List <Pair <Hook , HookData >> hookDataPairs , HookContext hookContext , String hookMethod , BiConsumer <Hook <T >, HookContext > hookCode ) {
62
+ if (hookDataPairs != null ) {
63
+ for (Pair <Hook , HookData > hookDataPair : hookDataPairs ) {
64
+ Hook hook = hookDataPair .getLeft ();
65
+ HookData hookData = hookDataPair .getRight ();
54
66
if (hook .supportsFlagValueType (flagValueType )) {
55
- executeChecked (hook , hookCode , hookMethod );
67
+ executeChecked (hook , hookData , hookContext , hookCode , hookMethod );
56
68
}
57
69
}
58
70
}
59
71
}
60
72
61
73
// before, error, and finally hooks shouldn't throw
62
- private <T > void executeChecked (Hook <T > hook , Consumer <Hook <T >> hookCode , String hookMethod ) {
74
+ private <T > void executeChecked (Hook <T > hook , HookData hookData , HookContext hookContext , BiConsumer <Hook <T >, HookContext > hookCode , String hookMethod ) {
63
75
try {
64
- hookCode .accept (hook );
76
+ var hookCtxWithData = hookContext .withHookData (hookData );
77
+ hookCode .accept (hook , hookCtxWithData );
65
78
} catch (Exception exception ) {
66
79
log .error (
67
80
"Unhandled exception when running {} hook {} (only 'after' hooks should throw)" ,
@@ -72,35 +85,42 @@ private <T> void executeChecked(Hook<T> hook, Consumer<Hook<T>> hookCode, String
72
85
}
73
86
74
87
// after hooks can throw in order to do validation
75
- private <T > void executeHooksUnchecked (FlagValueType flagValueType , List <Hook > hooks , Consumer <Hook <T >> hookCode ) {
76
- if (hooks != null ) {
77
- for (Hook hook : hooks ) {
88
+ private <T > void executeHooksUnchecked (FlagValueType flagValueType , List <Pair <Hook , HookData >> hookDataPairs , HookContext hookContext , BiConsumer <Hook <T >, HookContext > hookCode ) {
89
+ if (hookDataPairs != null ) {
90
+ for (Pair <Hook , HookData > hookDataPair : hookDataPairs ) {
91
+ Hook hook = hookDataPair .getLeft ();
92
+ HookData hookData = hookDataPair .getRight ();
78
93
if (hook .supportsFlagValueType (flagValueType )) {
79
- hookCode .accept (hook );
94
+ var hookCtxWithData = hookContext .withHookData (hookData );
95
+ hookCode .accept (hook , hookCtxWithData );
80
96
}
81
97
}
82
98
}
83
99
}
84
100
85
101
private EvaluationContext callBeforeHooks (
86
- FlagValueType flagValueType , HookContext hookCtx , List <Hook > hooks , Map <String , Object > hints ) {
102
+ FlagValueType flagValueType , HookContext hookCtx , List <Pair < Hook , HookData >> hookDataPairs , Map <String , Object > hints ) {
87
103
// These traverse backwards from normal.
88
- List <Hook > reversedHooks = new ArrayList <>(hooks );
104
+ List <Pair < Hook , HookData >> reversedHooks = new ArrayList <>(hookDataPairs );
89
105
Collections .reverse (reversedHooks );
90
106
EvaluationContext context = hookCtx .getCtx ();
91
-
107
+ /*
92
108
// Create hook data for each hook instance
93
109
Map<Hook, HookData> hookDataMap = new HashMap<>();
94
110
for (Hook hook : reversedHooks) {
95
111
if (hook.supportsFlagValueType(flagValueType)) {
96
112
hookDataMap.put(hook, HookData.create());
97
113
}
98
114
}
115
+ */
116
+
117
+ for (Pair <Hook , HookData > hookDataPair : reversedHooks ) {
118
+ Hook hook = hookDataPair .getLeft ();
119
+ HookData hookData = hookDataPair .getRight ();
99
120
100
- for (Hook hook : reversedHooks ) {
101
121
if (hook .supportsFlagValueType (flagValueType )) {
102
122
// Create a new context with this hook's data
103
- HookContext contextWithHookData = hookCtx .withHookData (hookDataMap . get ( hook ) );
123
+ HookContext contextWithHookData = hookCtx .withHookData (hookData );
104
124
Optional <EvaluationContext > optional = Optional .ofNullable (hook .before (contextWithHookData , hints ))
105
125
.orElse (Optional .empty ());
106
126
if (optional .isPresent ()) {
0 commit comments