Red Hat Training

A Red Hat training course is available for JBoss Enterprise SOA Platform

Chapter 23. Salience State Example

23.1. Salience State Example: State Class Example

public class State {
    public static final int NOTRUN   = 0;
    public static final int FINISHED = 1;

    private final PropertyChangeSupport changes =
        new PropertyChangeSupport( this );

    private String name;
    private int    state;

    ... setters and getters go here...
}
  • Each State class has fields for its name and its current state (see the class org.drools.examples.state.State). The two possible states for each objects are NOTRUN and FINISHED.

23.2. Salience State Example: Execution

State a = new State( "A" );
State b = new State( "B" );
State c = new State( "C" );
final State d = new State( "D" );

// By setting dynamic to TRUE, Drools will use JavaBean
// PropertyChangeListeners so you don't have to call modify or update().
boolean dynamic = true;

session.insert( a, dynamic );
session.insert( b, dynamic );
session.insert( c, dynamic );
session.insert( d, dynamic );

session.fireAllRules();
session.dispose(); // Stateful rule session must always be disposed when finished
  • Each instance is asserted in turn into the Session and then fireAllRules() is called.

23.3. Salience State Example: Executing Applications

Procedure 23.1. Task

  1. Open the class org.drools.examples.state.StateExampleUsingSalience in the Eclipse IDE.
  2. Right-click the class and select Run as... and then Java application. The following output will appear:
    A finished
    B finished
    C finished
    D finished
    

23.4. Salience State Example: Using Audit Logging with Operations

Procedure 23.2. Task

  1. To view the Audit log generated by an operation, open the IDE and click on Window and then select Show View, then Other..., Drools and Audit View.
  2. In the "Audit View" click the Open Log button and select the file <drools-examples-dir>/log/state.log.

23.5. Salience State Example: Rule "Bootstrap"

rule Bootstrap
    when
        a : State(name == "A", state == State.NOTRUN )
    then
        System.out.println(a.getName() + " finished" );
        a.setState( State.FINISHED );
end
Result:
rule "A to B"
    when
        State(name == "A", state == State.FINISHED )
        b : State(name == "B", state == State.NOTRUN )
    then
        System.out.println(b.getName() + " finished" );
        b.setState( State.FINISHED );
end
  • Every action and the corresponding changes appear in the Working Memory.
  • The assertion of the State object A in the state NOTRUN activates the Bootstrap rule, while the assertions of the other State objects have no immediate effect.
  • The execution of rule Bootstrap changes the state of A to FINISHED, which, in turn, activates rule "A to B".

23.6. Salience State Example: Rule "B to C"

rule "B to C"
        salience 10
    when
        State(name == "B", state == State.FINISHED )
        c : State(name == "C", state == State.NOTRUN )
    then
        System.out.println(c.getName() + " finished" );
        c.setState( State.FINISHED );
end
  • The conflict resolution strategy allows the engine's Agenda to decide which rule to fire.
  • As rule "B to C" has the higher salience value (10 versus the default salience value of 0), it fires first, modifying object C to state FINISHED.
  • The Agenda view can also be used to investigate the state of the Agenda, with debug points being placed in the rules themselves and the Agenda view opened.

23.7. Salience State Example: Rule "B to D"

rule "B to D"
    when
        State(name == "B", state == State.FINISHED )
        d : State(name == "D", state == State.NOTRUN )
    then
        System.out.println(d.getName() + " finished" );
        d.setState( State.FINISHED );
end
  • Rule "B to D" fires last, modifying object D to state FINISHED.
  • There are no more rules to execute and so the engine stops.

23.8. Salience State Example: Inserting a Dynamic Fact

// By setting dynamic to TRUE, JBoss Rules will use JavaBean
// PropertyChangeListeners so you don't have to call modify or update().
final boolean dynamic = true;

session.insert( fact, dynamic );
  • For the engine to see and react to changes of fact properties, the application must tell the engine that changes occurred. This can be done explicitly in the rules by using the modify statement, or implicitly by letting the engine know that the facts implement PropertyChangeSupport as defined by the JavaBeans specification.
  • The above example demonstrates how to use PropertyChangeSupport to avoid the need for explicit modify statements in the rules.
  • Ensure that your facts implement PropertyChangeSupport, the same way the class org.drools.example.State does.

23.9. Salience State Example: Setter with PropertyChangeSupport

public void setState(final int newState) {
    int oldState = this.state;
    this.state = newState;
    this.changes.firePropertyChange( "state",
                                     oldState,
                                     newState );
}
  • The setter for state in the class org.drools.examples.
  • When using PropertyChangeListener objects, each setter must implement a little extra code for the notification.

23.10. Salience State Example: Agenda Group Rules "B to C"

rule "B to C"
      agenda-group "B to C"
      auto-focus true       
  when
      State(name == "B", state == State.FINISHED )      
      c : State(name == "C", state == State.NOTRUN )
  then
      System.out.println(c.getName() + " finished" );
      c.setState( State.FINISHED );
      kcontext.getKnowledgeRuntime().getAgenda().getAgendaGroup( "B to D" ).setFocus();
end
Result:
rule "B to D"
      agenda-group "B to D"
  when
      State(name == "B", state == State.FINISHED )      
      d : State(name == "D", state == State.NOTRUN )
  then
      System.out.println(d.getName() + " finished" );
      d.setState( State.FINISHED );
end
  • By default, all rules are in the agenda group "MAIN".
  • The "agenda-group" attribute lets you specify a different agenda group for the rule. Initially, a Working Memory has its focus on the Agenda group "MAIN".
  • A group's rules will only fire when the group receives the focus. This can be achieved either by using the method setFocus() or the rule attribute auto-focus.
  • auto-focus means that the rule automatically sets the focus to its agenda group when the rule is matched and activated. It is this "auto-focus" that enables rule "B to C" to fire before "B to D".
  • The rule "B to C" calls setFocus() on the agenda group "B to D", allowing its active rules to fire, which allows the rule "B to D" to fire.

23.11. Salience State Example: Agenda Group Rules "B to D"

rule "B to D"
      agenda-group "B to D"
  when
      State(name == "B", state == State.FINISHED )      
      d : State(name == "D", state == State.NOTRUN )
  then
      System.out.println(d.getName() + " finished" );
      d.setState( State.FINISHED );
end

23.12. Salience State Example: Agenda Group Rules "D to E"

rule "D to E"
  when
      State(name == "D", state == State.FINISHED )      
      e : State(name == "E", state == State.NOTRUN )
  then
      System.out.println(e.getName() + " finished" );
      e.setState( State.FINISHED );
end
This produces the following expected output:
A finished
B finished
C finished
D finished
E finished
  • StateExampleWithDynamicRules adds another rule to the Rule Base after fireAllRules().