15 — Advanced
Action Chaining
Actions in rulii can be chained together using andBefore() and andThen() methods. This allows you to compose multi-step pipelines from simple, single-purpose actions without writing monolithic logic blocks.
andBefore() and andThen()
andBefore(action)
Executes the given action before this action
andThen(action)
Executes the given action after this action
Both methods return a ChainedAction that wraps the two actions and runs them in the correct order. You can chain as many actions as you like by calling these methods repeatedly.
Chaining Multiple Actions
import static org.rulii.model.action.Actions.action;
Action step1 = action(() -> System.out.println("Step 1"));
Action step2 = action(() -> System.out.println("Step 2"));
Action step3 = action(() -> System.out.println("Step 3"));
// Chain: step1 → step2 → step3
Action pipeline = step1.andThen(step2).andThen(step3);
pipeline.run(Bindings.builder().standard());
// Output: Step 1, Step 2, Step 3
Modifying Bindings in Sequence
// Modify binding values in sequence
Action chain = Action.builder()
.with((Binding<String> value) -> value.setValue("hello"))
.build()
.andThen(action((Binding<String> value) -> value.setValue(value.getValue() + " world")));
Bindings b = Bindings.builder().standard();
b.bind("value", "");
chain.run(b);
// value is now "hello world"
Using andBefore()
// andBefore: execute setup before main action
Action main = action(() -> System.out.println("Main"));
Action setup = action(() -> System.out.println("Setup"));
Action withSetup = main.andBefore(setup);
// Output: Setup, Main
No-Op Actions
Use Actions.EMPTY_ACTION() when you need a placeholder action that does nothing. This is useful as a default or when conditionally building chains.
Action noop = Actions.EMPTY_ACTION();
Action pipeline = noop.andThen(step1).andThen(step2);
// Only step1 and step2 actually execute
Using in Rules
Chained actions integrate seamlessly with the rule builder. Pass a chained action anywhere an action is expected:
Rule rule = Rule.builder()
.name("ProcessOrder")
.given(condition((Boolean approved) -> approved))
.then(action1.andThen(action2))
.build();
How ChainedAction Works
Internally, ChainedAction holds references to two actions and executes them in order. When you chain multiple actions, each call wraps the previous chain in a new ChainedAction, forming a linked sequence. The resulting structure is evaluated left to right, ensuring deterministic execution order.