OK, I'm not sure why this works, but it does. (As long as you're using java5 and
above and drools 4.0.7)
class File (
public Integer[] classState = {0,0,0,0,0,0,0,0,0,0};
public Integer[] getClassState() { return classState; }
}
Yes, it's an Integer[] and not an int[]. The public getter method AND the public
member variable are both required. This is really odd, but it works. Even with the
autoboxing of Integers, it would probably be faster than regex. You could avoid the
autoboxing if you defined static Integer objects and used them. (And the java compiler
might just do that behind the scenes since your autoboxing literals.)
dev d00ds, any idea why an int[] wouldn't work here? Should it? And why are both a
public getter and member variable necessary?
FYI, I tried a similar thing on drools 5. (The above was on drools 4.0.7) It didn't
work until I made the classState member a List<Integer> instead of an Integer[]. It
also didn't require a public getter, but did NOT work if the member variable was
private with a public getter!
class File {
public List<Integer> classState = Arrays.asList(0,0,0,0,0,0,0);
}
--- On Tue, 4/14/09, Charles Binford <Charles.Binford(a)Sun.COM> wrote:
From: Charles Binford <Charles.Binford(a)Sun.COM>
Subject: Re: [rules-users] How to traverse a hierarchy?
To: greg_barton(a)yahoo.com, "Rules Users List"
<rules-users(a)lists.jboss.org>
Date: Tuesday, April 14, 2009, 3:35 PM
Greg, I'm trying to test this out but am having trouble
getting things
to run. I'm not very experienced with java so I may be
doing something
stupid on that side of things also. Here are the key parts
of what I
have and the results I'm getting:
In my class called File I have the following:
public int[] classState = new int[]
{0,0,0,0,0,0,0,0,0,0};
....
public void setClassState(int idx, int val) {
int oldState = classState[idx];
if (oldState != val) {
classState[idx] = val;
changes.firePropertyChange("classState", oldState,
classState);
}
}
In my drl file:
rule "user rule 1.1"
agenda-group "classify"
salience 3
dialect "java"
when
$f : File(classState[0] == 1, classState[1] == 0 )
then
// do stuff
$f.setClassState(1,1);
end
AND the error I get when I run....
org.drools.RuntimeDroolsException: Exception executing
predicate eval(
classState[0] == 1 )
at
org.drools.rule.PredicateConstraint.isAllowed(PredicateConstraint.java:216)
at
org.drools.reteoo.AlphaNode.assertObject(AlphaNode.java:137)
.....
Caused by: org.mvel.CompileException: illegal use of []:
unknown type: null
Charles Binford
Greg Barton wrote:
> Edson's advice on this issue is spot on, but if
you want a more incremental approach you may try this:
optimize your hierarchy test. A regex string match is not
the fastest thing you could do to check what level the rule
is in, and that test is the one done most frequently.
(It's in every rule, and should be the first condition
in the LHS, right?) So some targetted optimization, if
possible, could be helpful. Could the hierarchy indicator
be an array of integers? The test for integer equality is
orders of magnitude faster than regex.
>
> when
> obj(level[0] == 1, level[1] == 2, level[2] == -1)
//-1 indicates unset
> ...
> then
> objSetLevel(2, 1); //Set level[2] == 1
> ....
> end
>
> Yes, messy looking, but probably a lot faster than
regex.
>
> And as for the "changing the contents of the
object and doing the update is not good for drools
performance" idea, I guess it matters what your purpose
is. Changing the contents of objects and having the rules
react to that change is what rules are for. :) If this is
something you intend to avoid you might want to look at
sequential mode processing.
>
> --- On Mon, 4/13/09, Charles Binford
<Charles.Binford(a)sun.com> wrote:
>
>
>> From: Charles Binford
<Charles.Binford(a)sun.com>
>> Subject: [rules-users] How to traverse a
hierarchy?
>> To: "Rules Users List"
<rules-users(a)lists.jboss.org>
>> Date: Monday, April 13, 2009, 4:56 PM
>> All, I'm trying to figure out a better way to
solve
>> this problem. I
>> have a batch of objects that I want matched
against a
>> hierarchy of
>> rules. I check the rules in order, and as soon as
I find a
>> match I'm
>> done for that level of the hierarchy. In other
words, If
>> the object
>> matches a rule, we'll check the rules
children, but not
>> the siblings.
>> Example:
>>
>> rule 1
>> rule 1.1
>> rule 1.2
>> rule 1.2.1
>> rule 1.2.2
>> rule 1.3
>> rule 2
>>
>> If an object matches rule 1, check for a match at
level
>> "1.*", but rule
>> 2 will never be checked. If an object matches 1,
1.2, and
>> 1.2.1, we're
>> done as 1.2.1 has no children.
>>
>> My current implementation with drools works, but
is very
>> inefficient. I
>> have a "level" string in the objects and
whenever
>> I find a match I
>> update the level of the object and force an object
update.
>> Each rule
>> tests that the level string is correct, e.g. rule
1.2.1
>> works as follows:
>> rule "1.2.1"
>> when
>> obj(level matches "1.2.*",.....)
>> ...
>> then
>> objSetLevel("1.2.1.*");
>> ....
>> end
>>
>> I'm also using saliance to keep the evaluation
order
>> like I want it.
>>
>> Changing the contents of the object and doing the
update is
>> not good for
>> drools performance as I understand it so I'm
looking
>> for a better way.
>> The hierarchy and the order of the matching is key
to my
>> application so
>> I'm not wanting to redesign that part of
things.
>>
>> I tried using activation-groups. That worked
great as long
>> as I only
>> had a single object to run through the hierarchy,
but given
>> the way the
>> rest of the system is design I need to load up
10-100
>> objects before
>> each call to fireallrules() for performance
purposes.
>>
>> Any suggestions are appreciated.
>>
>> Charles Binford
>>
>>
>> _______________________________________________
>> rules-users mailing list
>> rules-users(a)lists.jboss.org
>>
https://lists.jboss.org/mailman/listinfo/rules-users
>>
>
>
>
> _______________________________________________
> rules-users mailing list
> rules-users(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/rules-users
>