The property expression (see Property and property) allows the invocation of "safe" Java methods.
Rule sets often contain many instances of java.util.List.
The safe list of methods for java.util.List is included with CER:
# Safe list for java.util.List
contains.safe=true
containsAll.safe=true
get.safe=true
indexOf.safe=true
isEmpty.safe=true
lastIndexOf.safe=true
size.safe=true
subList.safe=true
# not exposed
hashCode.safe=false
listIterator.safe=false
iterator.safe=false
toArray.safe=false
# mutators - unsafe
add.safe=false
addAll.safe=false
clear.safe=false
remove.safe=false
removeAll.safe=false
retainAll.safe=false
While the description of these methods is available via the JavaDoc for java.util.List, the most typically useful properties are included here for your reference:
Returns true if this list contains no elements.
Returns the number of elements in this list.
Returns the element at the specified position in this list. Note that because CER passes round numeric values as instances of Number, you will need to use the intValue to convert a Number to an integer.
Returns true if this list contains the specified element.
<?xml version="1.0" encoding="UTF-8"?>
<RuleSet name="Example_UsefulListOperations"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=
"http://www.curamsoftware.com/CreoleRulesSchema.xsd">
<Class name="Person">
<!-- Exactly one Person (in each household) will
be designated as the head of household -->
<Attribute name="isHeadOfHousehold">
<type>
<javaclass name="Boolean"/>
</type>
<derivation>
<specified/>
</derivation>
</Attribute>
<!-- The children of this person. -->
<Attribute name="children">
<type>
<javaclass name="List">
<ruleclass name="Person"/>
</javaclass>
</type>
<derivation>
<specified/>
</derivation>
</Attribute>
<!-- Whether this person has any children.
Tests the isEmpty property of List. -->
<Attribute name="hasChildren">
<type>
<javaclass name="Boolean"/>
</type>
<derivation>
<not>
<property name="isEmpty">
<object>
<reference attribute="children"/>
</object>
</property>
</not>
</derivation>
</Attribute>
<Attribute name="numberOfChildren">
<type>
<javaclass name="Number"/>
</type>
<derivation>
<property name="size">
<object>
<reference attribute="children"/>
</object>
</property>
</derivation>
</Attribute>
<!-- This person's second child, if any, otherwise null -->
<Attribute name="secondChild">
<type>
<ruleclass name="Person"/>
</type>
<derivation>
<!-- We have to check whether the person has two
or more children -->
<choose>
<type>
<ruleclass name="Person"/>
</type>
<when>
<condition>
<compare comparison=">=">
<reference attribute="numberOfChildren"/>
<Number value="2"/>
</compare>
</condition>
<value>
<!-- Use the "get" property to get the second item
in the list - denoted by index 1 (lists in
Java are zero-based) -->
<property name="get">
<object>
<reference attribute="children"/>
</object>
<arguments>
<!-- The number must be converted to an integer
(as required by List.subList). -->
<property name="intValue">
<object>
<Number value="1"/>
</object>
</property>
</arguments>
</property>
</value>
</when>
<otherwise>
<!-- This person has no second child -->
<value>
<null/>
</value>
</otherwise>
</choose>
</derivation>
</Attribute>
<Attribute name="isChildOfHeadOfHousehold">
<type>
<javaclass name="Boolean"/>
</type>
<derivation>
<property name="contains">
<object>
<!-- The children of the head of household -->
<reference attribute="children">
<!-- retrieve the single Person rule object which
has isHeadOfHousehold equal to true-->
<singleitem onEmpty="error" onMultiple="error">
<readall ruleclass="Person">
<match retrievedattribute="isHeadOfHousehold">
<true/>
</match>
</readall>
</singleitem>
</reference>
</object>
<!-- check whether the list of the head of household's
children contains THIS Person -->
<arguments>
<this/>
</arguments>
</property>
</derivation>
</Attribute>
</Class>
</RuleSet>