05 — Core
RuleContext
A RuleContext is the execution environment that holds everything a rule needs to run: bindings, locale, converters, message formatters, a tracer, a clock, and an executor service.
Creating a RuleContext
// From bindings
Bindings bindings = Bindings.builder().standard();
bindings.bind("name", "Alice");
RuleContext ctx = RuleContext.builder().build(bindings);
// From lambda declarations
RuleContext ctx2 = RuleContext.builder().build(name -> "Alice", age -> 30);
What's Inside a RuleContext?
| Component | Purpose |
|---|---|
| Bindings | Shared variable workspace |
| Matching Strategy | Rule parameter matching strategy |
| Locale | For locale-aware formatting |
| ConverterRegistry | Type conversion between binding values |
| MessageResolver | Looks up message templates |
| MessageFormatter | Formats messages with placeholders |
| Tracer | Logs rule execution for debugging |
| Clock | Provides current time (useful for testing) |
| ExecutorService | For async rule execution |
When Do You Need a RuleContext?
Most of the time, you don't need to create one manually. When you call rule.run(bindings) or rule.run(name -> "Alice"), a default context is created for you. Create one explicitly when you need to customize locale, converters, or tracing.
// Running with an explicit context
RuleContext ctx = RuleContext.builder().build(name -> "Alice");
RuleResult result = rule.run(ctx);
Accessing Context Inside a Rule
In annotated rules, you can receive the RuleContext as a parameter:
@Given
public boolean when(RuleContext context) {
Bindings bindings = context.getBindings();
return bindings.contains("name");
}