Rule Classes

Any CER rule class defined in your rule set may be used as a data type in the same rule set.

<?xml version="1.0" encoding="UTF-8"?>
<RuleSet name="Example_ruleclassDataType"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation=
"http://www.curamsoftware.com/CreoleRulesSchema.xsd">
  <Class name="Person">

    <Attribute name="firstName">
      <type>
        <javaclass name="String"/>
      </type>
      <derivation>
        <specified/>
      </derivation>
    </Attribute>

    <Attribute name="favoritePet">
      <type>
        <!-- The type of this attribute is a rule class
             defined elsewhere in this rule set.        -->
        <ruleclass name="Pet"/>
      </type>
      <derivation>
        <specified/>
      </derivation>
    </Attribute>

  </Class>

  <Class name="Pet">

    <Attribute name="name">
      <type>
        <javaclass name="String"/>
      </type>
      <derivation>
        <specified/>
      </derivation>
    </Attribute>

  </Class>

</RuleSet>

Inheritance

CER supports simple implementation inheritance for rule classes.

A rule class may optionally specify an extends declaration to sub-class another rule class in the same rule set.

A sub-rule class inherits the calculated rule attributes of all its ancestor classes, and optionally may override any of these attributes to provide different derivation calculation rules.

A sub-rule class also inherits the initialized rule attributes of all its ancestor classes, and any create expression for the sub-rule class must specify the value of the initialized attributes for all the ancestor rule classes of the sub-rule class ahead of any declared on the sub-rule class itself.

CER allows an attribute to be declared abstract. Every rule class that defines or inherits (but does not override) an abstract attribute must itself be declared abstract. An abstract class cannot be used in a create expression.

CER will allow a rule object instance of a rule class to be returned wherever one of its ancestor rule classes is expected.

The CER rule set validator will report an error if an expression in your rule set attempts to return an incompatible value:

<?xml version="1.0" encoding="UTF-8"?>
<RuleSet name="Example_ruleclassInheritance"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation=
"http://www.curamsoftware.com/CreoleRulesSchema.xsd">


  <!-- The CER rule set validator will insist that this
       rule class is marked abstract, because it contains
       an abstract rule attribute. -->
  <Class name="Resource" abstract="true">
    <Initialization>
      <!-- Whenever a Resource rule object is created,
           its owner must be initialized.

           Since Resource is abstract, it cannot itself be
           used in a <create> expression, only concrete
           subclasses can. -->
      <Attribute name="owner">
        <type>
          <ruleclass name="Person"/>
        </type>
      </Attribute>
    </Initialization>


    <!-- The monetary value of the resource. -->
    <Attribute name="value">
      <type>
        <javaclass name="Number"/>
      </type>
      <derivation>
        <!-- Every resource has an amount, but it's
             calculated in a sub-class-specific way. -->
        <abstract/>
      </derivation>
    </Attribute>
  </Class>

  <!-- A building is a type of resource. -->
  <Class name="Building" extends="Resource">
    <!-- The physical address of the building,
         e.g. 123 Main Street.

         The address value must be specified
         in addition to the inherited owner
         rule attribute, which is an
         initialized attribute on the super-rule
         class. -->
    <Initialization>
      <Attribute name="address">
        <type>
          <javaclass name="String"/>
        </type>
      </Attribute>
    </Initialization>


    <!-- Building is a concrete class
         (no pun intended!), and so the CER
         rule set validator will insist that this
         class inherits or declares a calculation
         for all inherited abstract rule attributes. -->
    <Attribute name="value">
      <type>
        <javaclass name="Number"/>
      </type>
      <derivation>
        <arithmetic operation="-">
          <reference attribute="purchasePrice"> </reference>
          <reference attribute="outstandingMortgageAmount"/>
        </arithmetic>

      </derivation>
    </Attribute>

    <!-- The price originally paid for the building. -->
    <Attribute name="purchasePrice">
      <type>
        <javaclass name="Number"/>
      </type>
      <derivation>
        <specified/>
      </derivation>
    </Attribute>

    <!-- The amount of outstanding loans or mortgages against
         this building. -->
    <Attribute name="outstandingMortgageAmount">
      <type>
        <javaclass name="Number"/>
      </type>
      <derivation>
        <specified/>
      </derivation>
    </Attribute>

  </Class>

  <Class name="Vehicle" extends="Resource">
    <Initialization>
      <Attribute name="registrationPlate">
        <type>
          <javaclass name="String"/>
        </type>
      </Attribute>
    </Initialization>

    <Attribute name="value">
      <type>
        <javaclass name="Number"/>
      </type>
      <derivation>
        <!-- The value of this type of Resource is
             directly specified, rather than calculated.-->
        <specified/>

      </derivation>
    </Attribute>

  </Class>

  <Class name="Person">

    <!-- A sample attribute showing how initialized attributes
         are inherited. -->
    <Attribute name="sampleBuilding">
      <type>
        <ruleclass name="Building"/>
      </type>
      <derivation>
        <create ruleclass="Building">
          <!-- The first initialized rule attribute
               is inherited from Resource.

               Set this person to be the owner -->
          <this/>
          <!-- The second initialized rule attribute
            is specified directly on Building.

            Set the address of the Building. -->
          <String value="123 Main Street"/>
        </create>
      </derivation>
    </Attribute>

    <!-- a sample attribute which shows how a Building can be
         returned as a Resource (because a Building *IS* a
         Resource -->
    <Attribute name="sampleResource">
      <type>
        <ruleclass name="Resource"/>
      </type>
      <derivation>
        <reference attribute="sampleBuilding"/>
      </derivation>
    </Attribute>


  </Class>

</RuleSet>

The Root Rule Class

If a rule class does not specify another rule class to extend, then the rule class automatically extends CER's "root" rule class, which contains a single description rule attribute.

The description rule attribute provides a localizable description of the rule object instance. Rule classes are free to override the derivation of the description rule calculation for their rule object instances.

Every rule class ultimately inherits from the root rule class (and thus contains a description rule attribute), similar to the way that all Java classes ultimately inherit from java.lang.Object.

The default implementation of the description rule attribute, supplied by the root rule class, uses the defaultDescription expression.