Russ,
The problem with your sample is that Drools works with JavaBeans and
to be a JavaBean you need your Group class to implement getResources()
method. Follow the answers:
1. Am I allowed to use a fact binding inside the predicate condition?
Yes, you are. See sample rule 1 bellow.
2. How come the $resources field binding doesn't work?
Drools looks for a getXXX() method for the fields you want to bind. Your
class does not have one. Maybe we can support direct field access in the
future, but I don't know if it is good for real systems....
3. Would I be allowed to use the == operator with a fact binding? For
example, assume class Group had an attribute "resource" of type
Resource: "$g : Group(resource == $r)"
You are allowed to use ==, but this will cause the equals() method to be
called, and in your example, you would compare a list to a single object
and equals would return false.
4. If 3 wouldn't work, can I use the return value predicate when the
expression returns an object, as in: "$g: Group(resource == ($r))"?
Not sure what you mean.
Follows how you could implement your example:
public class Resource {
}
public class Group {
private List<Resource> resources = new ArrayList<Resource>();
public List<Resource> getResources() {
return resources;
}
public void setResources(List<Resource> resources) {
this.resources = resources;
}
}
And now the rule file would be:
-----------
package com.sample
import com.sample.Group;
import com.sample.Resource;
rule "Authorized Resources"
when
$r : Resource()
$g : Group( $resources:resources -> ( $resources.contains( $r ) ) )
then
System.out.println( "Rule 1 ok" );
end
rule "Authorized Resources 2"
when
$r : Resource()
$g : Group( $resources:resources contains $r )
then
System.out.println( "Rule 2 ok" );
end
-------------
As you can see above you can use either a predicate (as in your
previous try) or use the "contains" operator (rule 2) that is only
syntax sugar to the contains method.
Look at the integration test cases and you will find several
interesting samples.
Let me know if there are any other questions.
Regards,
Edson
Russ Egan wrote:
I've got two classes:
public class Resource {
}
public class Group {
public List<Resource> resources = new ArrayList<Resource>();
}
I want to test whether there is a resource which is contained by a
group. In 2.5, the test looked like:
<rule name="Authorized resources" >
<parameter identifier="group">
<class>model.Group</class>
</parameter>
<parameter identifier="res">
<class>model.Resource</class>
</parameter>
<g:condition>
group.resources.contains(res)
</g:condition>
<g:consequence>
// do something
</g:consequence>
</rule>
In 3.0, I tried this:
rule "Authorize Resources"
when
$r : Resource()
$g : Group($resources : resources -> ($resources.contains($r)))
then
# do something
end
Doesn't work though. I get a "Unable to create field extractor:
$resources" error. So:
1. Am I allowed to use a fact binding inside the predicate condition?
2. How come the $resources field binding doesn't work?
3. Would I be allowed to use the == operator with a fact binding? For
example, assume class Group had an attribute "resource" of type
Resource: "$g : Group(resource == $r)"
4. If 3 wouldn't work, can I use the return value predicate when the
expression returns an object, as in: "$g: Group(resource == ($r))"?
Generally, it seems the predicates are designed to work with boxed
primitives. But my fact database is a map of pojos, many with
attributes which are collections of other pojos. Seems like I won't
be able to use the simple operators at all. Are there plans in 3.1 to
make the operators (like == and contains) work with pojos?
Thanks.
--
---
Edson Tirelli
Auster Solutions do Brasil
@ www.auster.com.br
+55 11 5096-2277 / +55 11 9218-4151