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.