Werecat Introduction

The Werecat Rules Engine is a freely available framework for building and evaluating simple, hierarchical rule structures. Using Java reflection, you can easily plug in your own data and functions to create a highly dynamic rules-based structure with very little coding effort. The rest of this document describes how to use the framework for your own projects.

Sample Rules

The rules format is simple JSON, which looks like this:

{
  "top": "testOverride",
  "version": "0.0",
  "rules": {
    "testOverride": {
        "description": "Check for override",
        "condition": "setting != null",
        "accept": "doOverride",
        "decline": "testLocation"
    },
    "testLocation": {
        "description": "Check if location is present",
        "condition": "location != null",
        "accept": "useLocation",
        "decline": "doNothing()",
    },
    ...

The core structure is a list of tagged rules. The outer "top" tag identifies the default entry point for evaluating rules, and the "version" tag is merely for tracking changes. Each rule element has a name, used to reference the tree, and four attributes:

The condition is similar to an expression in C++, Java, or other programming languages, and may use all the similar operators (+,-,*,/,>,<, etc). You can work with both numbers and strings, including regular expression matching. Pseudo variables can be attached to your own data objects as described in the next section.

Actions (accept or decline), can consist of two components:

If you are using only a single action, simply include that action. If you are multiple actions, separate them by semicolons. (You may also omit the action entirely if not needed). A fully loaded action might look like this:

"action": "myMethod();nextTag"

Typically, the method will be used to update status in your Context object, as explained in the next section.

Sample Code

The most important class when using the Rule Engine is the RuleContext. Each time you evaluate a Rule, you should create a RuleContext that stores all the inputs needed in the rule engine, and has the ability to store any outputs you want. You should implement RuleContext on your own class to expose fields and methods you want to use in the rules, like this:

public class ExampleContext implements RuleContext {
    // Inputs
    int level; // Some sample value

    // Results
    int action = 0;

    // Getter
    public int getLevel() {
	return level;
    }
    // Action
    public void setBasicAction() {
	action = 1;
    }
}

Because there is a method call getLevel, you may now use the variable level in your conditions (like "level != 2").

Actions can call any public method of your RuleContext. You can use any information you need from the context, including updating input values, or setting outputs.

Using the rule engine itself is very simple. First, import the package:

import com.whicken.werecat.*;

Second, instantiate the engine with some JSON rules as input:

RuleFactory factory = new RuleFactory(ExampleContext.class);
RuleEngine engine = new RuleEngine();
engine.load(file, factory);

The RuleContext being used must be passed in via the RuleFactory, so that the actions and conditions may be validated during instantiation. To evaluate a rule, create your context, and pass it in to the evaluate method. This will walk the rule structure, calling the appropriate actions, and return when completed.

ExampleContext context = new ExampleContext();
context.level = 4;
engine.evaluate(context);
System.out.println("Result: "+context.action);

[Back to Werecat Home]