Greetings fellow Droolers,
Each of our rules modifies the fact it matches. We'd like to run each of
those rules exactly once, not reactivating them when a fact changes. I see
from the archives that I'm not the first person to discover that no-loop is
too weak and lock-on-activate too strong for my purposes.
I implemented our requirement with an AgendaListener that remembers hashes
of rules + facts. This works but requires each fact to implement an
interface with a method that returns the hash, and means TWO casts each time
I examine a FactHandle. The whole AgendaFilter is below so you can see what
I mean.
Can anyone suggest a better way? I'm looking more for a better approach
altogether than I am for critique of the implementation of my current
approach, although the latter would not be unwelcome.
private static class Once
implements AgendaFilter {
private final Set<Integer> alreadyActivatedRules = new
HashSet<Integer>();
public boolean accept(Activation activation) {
int hash = activation.getRule().getName().hashCode();
for (FactHandle handle: activation.getFactHandles()) {
Object object = ((DefaultFactHandle) handle).getObject();
hash *= 31;
if (object instanceof Identifiable) {
hash += ((Identifiable) object).getIdentity();
} else if (object instanceof String) {
// We get here when a rule uses from on a string collection
hash += object.hashCode();
} else {
throw new IllegalStateException(
"Don't know what to do with fact class "
+ object.getClass() + ", value " + object);
}
}
boolean accept = !alreadyActivatedRules.contains(hash);
alreadyActivatedRules.add(hash);
return accept;
}
}
Thanks & cheers,
--
| Dave Schweisguth
http://schweisguth.org/~dave/ |
| Home: dave at
schweisguth.org Work:
http://www.nileguide.com/ |
| For compliance with the NJ Right to Know Act: Contents partially unknown |