Another option is to use 'from'. I didn't tested that, but it should work fine in trunk.

There is a Person
Whose address areaCode equals '415'

    Would be mapped to:

when
  p: Person()
  a: Address( areaCode == '415' ) from p.addresses
then
  ...
end

    Note that the kind of flexibility you are trying to achieve is not simple by nature do to in a template engine (like DSL).

    Good luck and let us know plz how it goes.

    Regards,
     Edson

2007/6/29, Michael Neale <michael.neale@gmail.com >:
Hi Matt.

yeah mapping deep hierarchies in a way that anyone can understand is not that easy. You can have helper methods on your objects to give you functionality. eg if you don't care which address you are talking about, then you could do something like:

Person ( .... , (hasAddress("blah")) )

assuming there is a hasAddress method on Person - which then iterates through for you. Or you have a function to do it for you.

You can do things like

There is a Person
  - has an address of 'blah'

where -has an address of '{blah}'==(checkAddress(this, "{blah}") )
that will use a function checkAddress, and apply it to the fact (which is the Person). So you can span lines that way rather then coming up with combinations.





On 6/26/07, Matt Geis < mgeis@yahoo.com> wrote:
Hi,
I'm encountering some conceptual issues trying to get something done with JBossRules.

What I'd like to do is to create a DSL that allows our non-technical users to have some very flexible options for accessing nested properties in an object.

Ideally I'd like to allow them to....

1.  Access certain cryptically named properties by easy-to-understand aliases.
2.  Use boolean operators such as and/or
3.  Use comparators such as ==, >, <, etc.
4.  Use the above in nested clauses (see below).

For example, take a Person, which has the following properties...

String name
Date birthdate
Address[] addresses
Phone[] phones

Address has the following properties:
String street, city, state, zip;

Phone has...
String areaCode, exchange, line:

Most frequently, the rules will operate to find out if a given object
in a nested collection meets certain property criteria, and if so, to
identify the first object that does and call out that fact in the THEN
clause of the rule.

Here's a sample use case.  If the user has one or more phones with an area code of "415", print "San Francisco".

Pseudo-code...

rule
    when
        There is a person with a phone with area code equals '415'
    then
       Output "San Francisco"
end

So, "there is a person" clearly equates to something like p:Person()...

but where I'm getting stuck is the rest of it.  I dont' want to come up with ALL possible permutations of the object's properties, so having
something like p:Person(phone[0].areaCode == '415') is not an option.  Not only does it fail to address ALL the phones, it's hard-coded.

I couldn't find any documentation on using the 'contains' operator for anything other than Collections of Strings ($shop.cheeses contains 'stilton').  I could imagine something like...

in DRL: p:Person(phones contains phone.areaCode == '415')  (yes, very pseudocode, I know)

Other thoughts I've had, but I have no experience with them, are whether MVEL projections or accumulator functions would be of use.  I could see ways where I could find out if a nested item met certain criteria (project all area codes for phones into a collection, then see if that collection 'contains' the desired value, or use an accumulator function to examine all objects and capture the index of the first one that matches).  Although that might work (as I said, not sure here), I'm still not seeing how to do this and still keep the end user flexibility I'm hoping for.

I'd like to have a list of names, like 'area code'  maps to 'areaCode' and 'street address' maps to 'street', and the user could plug them in on their own, so they could just as easily also write (with no changes to the DSL)...

There is a person with an address with state equals 'MA'

I've thought about somehow using an eval() call, but I can't capture the entire criteria string and pass it to a function in a global helper (the DSL doesn't expand it, and just sends the String literal "{criteria}"
Even if that did work, I don't like the idea of circumventing the declarative nature of the rules language.

I'd LOVE to be able to express this all in one rule, as it's business users who will be working with the DSL.  If it were programmers, I'd probably be ok with asking them to assert the Phone[], and have some other rule act on that, but I don't think that will work for me.

On a side note, is there documentation or examples anywhere for getting nested properties and using MVEL?

Any help and suggestions greatly appreciated.

Thanks,
Matt





____________________________________________________________________________________Ready for the edge of your seat?
Check out tonight's top picks on Yahoo! TV.
http://tv.yahoo.com/
_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users


_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users




--
  Edson Tirelli
  Software Engineer - JBoss Rules Core Developer
  Office: +55 11 3529-6000
  Mobile: +55 11 9287-5646
  JBoss, a division of Red Hat @ www.jboss.com