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/