I have modified my application to allow adding/removing/updating rules during
runtime. However, when I add a new rule to the rulebase, I don't get the
behavior I expect.
First, as soon as I call RuleBase.addPackage(), the new rules fire (the RHS code
runs). Shouldn't that happen only when I call fireAllRules()?
Second, newly added collect() rules don't collect already asserted objects. New
non-collect rules can see the objects just fine.
Attached is a testcase, and below is the output it produces. Am I doing
something wrong, or is this a bug? I'm running Drools 4.0.3 on JDK 1.5.0.13.
Start
RuleBase created
Adding rules about 'tom':
package rules;
import java.util.ArrayList;
import test.Tester.Record;
import test.Tester;
rule "Collect tom"
when
$list : ArrayList(size > 0) from collect( Record(field1 == "tom") )
then
Tester.show($list, "Collect tom");
end
rule "Non collect tom"
when
$rec : Record( field1 == "tom" )
then
System.out.println("Find 'tom' " + $rec.dump());
end
inserting record 1:"tom",
inserting record 2:"fred",
inserting record 3:"harry",
inserting record 4:"fred",
inserting record 5:"ed",
inserting record 6:"tom",
inserting record 7:"sreeni",
inserting record 8:"jill",
inserting record 9:"ralph",
inserting record 10:"tom",
fireAllRules()
Find 'tom' 10:"tom",
'Collect tom' collected 3 records => 1:"tom", 6:"tom", 10:"tom",
Find 'tom' 6:"tom",
Find 'tom' 1:"tom",
adding rules about 'fred':
package morerules;
import java.util.ArrayList;
import test.Tester.Record;
import test.Tester;
rule "Collect fred"
when
$list : ArrayList(size > 0) from collect( Record(field1 == "fred") )
then
Tester.show($list, "Collect fred");
end
rule "Non collect fred"
when
$rec : Record( field1 == "fred" )
then
System.out.println("Find 'fred' " + $rec.dump());
end
==> Why do the new rules fire when added?
Find 'fred' 4:"fred",
Find 'fred' 2:"fred",
'Collect fred' collected 0 records =>
==> Why doesn't the collect rule collect? The non-collect rule works.
fireAllRules()
Changing record 3 to 'fred'
fireAllRules()
Find 'fred' 3:"fred",
'Collect fred' collected 1 records => 3:"fred",
==> Why does the collect rule not see the other two 'fred' records?
--
Dirk Bergstrom [EMAIL PROTECTED]
_____________________________________________
Juniper Networks Inc., Computer Geek
Tel: 408.745.3182 Fax: 408.745.8905
package test;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.drools.FactHandle;
import org.drools.RuleBase;
import org.drools.RuleBaseConfiguration;
import org.drools.RuleBaseFactory;
import org.drools.WorkingMemory;
import org.drools.compiler.DroolsParserException;
import org.drools.compiler.PackageBuilder;
import org.drools.compiler.PackageBuilderConfiguration;
import org.drools.rule.builder.dialect.java.JavaDialectConfiguration;
public class Tester {
private static String RULES_TOM =
"package rules;\n" +
"import java.util.ArrayList;\n" +
"import test.Tester.Record;\n" +
"import test.Tester;\n" +
"rule \"Collect tom\"\n" +
"when\n" +
" $list : ArrayList(size > 0) from collect( Record(field1 == \"tom\") )\n" +
"then\n" +
" Tester.show($list, \"Collect tom\");\n" +
"end\n\n" +
"rule \"Non collect tom\"\n" +
"when\n" +
" $rec : Record( field1 == \"tom\" )\n" +
"then\n" +
" System.out.println(\"Find 'tom' \" + $rec.dump());\n" +
"end";
private static String RULES_FRED =
"package morerules;\n" +
"import java.util.ArrayList;\n" +
"import test.Tester.Record;\n" +
"import test.Tester;\n" +
"rule \"Collect fred\"\n" +
"when\n" +
" $list : ArrayList(size > 0) from collect( Record(field1 == \"fred\") )\n" +
"then\n" +
" Tester.show($list, \"Collect fred\");\n" +
"end\n\n" +
"rule \"Non collect fred\"\n" +
"when\n" +
" $rec : Record( field1 == \"fred\" )\n" +
"then\n" +
" System.out.println(\"Find 'fred' \" + $rec.dump());\n" +
"end";
static String[][] MYDATA = {
{ "1", "tom", },
{ "2", "fred", },
{ "3", "harry", },
{ "4", "fred", },
{ "5", "ed", },
{ "6", "tom", },
{ "7", "sreeni", },
{ "8", "jill", },
{ "9", "ralph", },
{ "10", "tom", },
};
public static void show(ArrayList rs, String msg) {
System.out.print("'" + msg + "' collected " + rs.size() +
" records => ");
for (Object r : rs) {
System.out.print(((Record) r).dump());
}
System.out.println("");
}
static Record setup(WorkingMemory workingMemory) {
Record testrec = null;
for (String[] data: MYDATA) {
Record rec = new Record(data);
System.out.println("inserting record " + rec.dump());
rec.setFactHandle(workingMemory.insert(rec));
if (rec.id.equals("3")) testrec = rec;
}
return testrec;
}
public static void doit() throws Exception {
System.out.println("Start");
PackageBuilderConfiguration pkgBuilderCfg = new PackageBuilderConfiguration();
JavaDialectConfiguration javaConf = (JavaDialectConfiguration)
pkgBuilderCfg.getDialectConfiguration("java");
javaConf.setCompiler(JavaDialectConfiguration.JANINO);
javaConf.setJavaLanguageLevel("1.5");
RuleBase ruleBase = RuleBaseFactory.newRuleBase();
System.out.println("RuleBase created");
System.out.println("Adding rules about 'tom':\n" + RULES_TOM + "\n");
addRule(pkgBuilderCfg, ruleBase, RULES_TOM);
WorkingMemory workingMemory = ruleBase.newStatefulSession();
Record testrec = setup(workingMemory);
System.out.println("\nfireAllRules()");
workingMemory.fireAllRules();
System.out.println("\nadding rules about 'fred':\n" + RULES_FRED + "\n");
System.out.println(" ==> Why do the new rules fire when added?");
addRule(pkgBuilderCfg, ruleBase, RULES_FRED);
System.out.println(" ==> Why doesn't the collect rule collect?" +
" The non-collect rule works.");
System.out.println("fireAllRules()");
workingMemory.fireAllRules();
testrec.field1 = "fred";
System.out.println("\nChanging record 3 to 'fred'");
workingMemory.update(testrec.factHandle, testrec);
System.out.println("fireAllRules()");
workingMemory.fireAllRules();
System.out.println(" ==> Why does the collect rule not see the other " +
"two 'fred' records?");
}
private static void addRule(PackageBuilderConfiguration pkgBuilderCfg,
RuleBase ruleBase, String rules) throws DroolsParserException,
IOException, Exception {
PackageBuilder rulePackageBuilder = new PackageBuilder(pkgBuilderCfg);
rulePackageBuilder.addPackageFromDrl(new StringReader(rules));
if (rulePackageBuilder.hasErrors()) {
throw new Exception("Errors parsing rule : " +
rulePackageBuilder.getErrors().toString());
}
ruleBase.addPackage(rulePackageBuilder.getPackage());
}
public static class Record {
public String id;
public String field1;
public FactHandle factHandle;
public Record(String[] values) {
this.id = values[0];
field1 = values[1];
}
public void setFactHandle(FactHandle factHandle) {
this.factHandle = factHandle;
}
public String getfield1() {
return field1;
}
public String dump() {
return this.id + ":\"" + this.field1 + "\", ";
}
}
public static final void main(String[] args) {
try {
doit();
} catch (Throwable t) {
t.printStackTrace();
}
}
}
_______________________________________________
rules-users mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/rules-users