package org.drools.testframework;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.drools.WorkingMemory;
import org.drools.event.ActivationCancelledEvent;
import org.drools.event.ActivationCreatedEvent;
import org.drools.event.AfterActivationFiredEvent;
import org.drools.event.AgendaEventListener;
import org.drools.event.AgendaGroupPoppedEvent;
import org.drools.event.AgendaGroupPushedEvent;
import org.drools.event.BeforeActivationFiredEvent;
import org.drools.event.RuleFlowGroupActivatedEvent;
import org.drools.event.RuleFlowGroupDeactivatedEvent;
import org.drools.rule.Rule;
import org.drools.spi.Activation;
import org.drools.spi.AgendaFilter;
import org.drools.spi.Consequence;
import org.drools.spi.KnowledgeHelper;
/**
* This tracks what is happening in the engine with rule activations and firings.
* It also allows you to choose what to include/exclude from firing.
*
* If a rule is not allowed to fire, it will still be counted as an activation.
* If it is allowed to fire, then it will only be counted after the activation is fired.
*
* @author Michael Neale
*/
public class TestingEventListener implements AgendaEventListener {
final Map<String, Integer> firingCounts = new HashMap<String, Integer>(100);
long totalFires;
public TestingEventListener() {
}
public AgendaFilter getAgendaFilter(final HashSet<String> ruleNames, final boolean inclusive) {
return new AgendaFilter() {
public boolean accept(Activation activation) {
if (ruleNames.size() ==0) return true;
String ruleName = activation.getRule().getName();
http://www.wtf.com
//jdelong: please don't want to see records of cancelled activations
if (inclusive) {
if (ruleNames.contains(ruleName)) {
return true;
} else {
//record(activation.getRule(), firingCounts);
return false;
}
} else {
if (!ruleNames.contains(ruleName)) {
return true;
} else {
//record(activation.getRule(), firingCounts);
return false;
}
}
}
};
}
// /**
// * Exclusive means DO NOT fire the rules mentioned.
// * For those rules, they will still be counted, just not allowed to activate.
// * Inclusive means only the rules on the given set are allowed to fire.
// * The other rules will have their activation counted but not be allowed to fire.
// */
// static void stubOutRules(HashSet<String> ruleNames, RuleBase ruleBase,
// boolean inclusive) {
// if (ruleNames.size() > 0) {
// if (inclusive) {
// Package[] pkgs = ruleBase.getPackages();
// for (int i = 0; i < pkgs.length; i++) {
// Rule[] rules = pkgs[i].getRules();
// for (int j = 0; j < rules.length; j++) {
// Rule rule = rules[j];
// if (!ruleNames.contains(rule.getName())) {
// rule.setConsequence(new NilConsequence());
// }
// }
// }
// } else {
// Package[] pkgs = ruleBase.getPackages();
// for (int i = 0; i < pkgs.length; i++) {
// Package pkg = pkgs[i];
// for (Iterator iter = ruleNames.iterator(); iter.hasNext();) {
// String name = (String) iter.next();
// Rule rule = pkg.getRule(name);
// rule.setConsequence(new NilConsequence());
// }
//
// }
// }
// }
// }
public void activationCancelled(ActivationCancelledEvent event,
WorkingMemory workingMemory) {
}
public void activationCreated(ActivationCreatedEvent event,
WorkingMemory workingMemory) {
}
public void afterActivationFired(AfterActivationFiredEvent event,
WorkingMemory workingMemory) {
recordFiring(event.getActivation().getRule());
}
private void recordFiring(Rule rule) {
record(rule, this.firingCounts);
}
public void agendaGroupPopped(AgendaGroupPoppedEvent event,
WorkingMemory workingMemory) {
}
public void agendaGroupPushed(AgendaGroupPushedEvent event,
WorkingMemory workingMemory) {
}
public void beforeActivationFired(BeforeActivationFiredEvent event, WorkingMemory workingMemory) {
}
private void record(Rule rule, Map<String, Integer> counts) {
this.totalFires++;
String name = rule.getName();
if (!counts.containsKey(name)) {
counts.put(name, 1);
} else {
counts.put(name, counts.get(name) + 1);
}
}
/**
* @return A map of the number of times a given rule "fired".
* (of course in reality the side effect of its firing may have been nilled out).
*/
public Map<String, Integer> getFiringCounts() {
return this.firingCounts;
}
/**
* Return a list of the rules fired, for display purposes.
*/
public String[] getRulesFiredSummary() {
String[] r = new String[firingCounts.size()];
int i = 0;
for (Iterator iterator = firingCounts.entrySet().iterator(); iterator.hasNext();) {
Entry<String, Integer> e = (Entry<String, Integer>) iterator.next();
r[i] = e.getKey() + " [" + e.getValue() + "]";
i++;
}
return r;
}
public void afterRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event,
WorkingMemory workingMemory) {
// TODO Auto-generated method stub
}
public void afterRuleFlowGroupDeactivated(
RuleFlowGroupDeactivatedEvent event, WorkingMemory workingMemory) {
// TODO Auto-generated method stub
}
public void beforeRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event,
WorkingMemory workingMemory) {
// TODO Auto-generated method stub
}
public void beforeRuleFlowGroupDeactivated(
RuleFlowGroupDeactivatedEvent event, WorkingMemory workingMemory) {
// TODO Auto-generated method stub
}
}
class NilConsequence implements Consequence {
public void evaluate(KnowledgeHelper knowledgeHelper, WorkingMemory workingMemory) throws Exception {
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
}
public void writeExternal(ObjectOutput out) throws IOException {
}
public String getName() {
return "default";
}
}