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


Reply via email to