Validating complex relations

From FlexRule Wiki
Jump to: navigation, search

Assumptions

In this article we discussed how an inheritance relation can be validated based on the concrete types of the objects. Now consider a more complex model that has aggregation and composition as well. Assume in your application you have the following model.

Contact model

In this model a contact may have more than one address and more than one number. We are going to extend the previous article`s rule to cover more validations.

Rules

In the article we are going to define the following rules

  1. a contact must have at lease one address
  2. Address of a contact can not be duplicated
  3. Phone of a contact can not be duplicated
  4. Line1 property of each contact`s address can not be null or empty

Detecting duplication

When there is a collection and uniqueness of the items in collection need to be validated you can use UniqueConstraint command. This command enforces the uniqueness based on combination of properties value.

  1. <Logic name="allAddressLine1_UniqueConstraint">
  2.   <And>
  3.     <UniqueConstraint>
  4.       <Add property="Line1"/>
  5.       <Add property="Line2"/>
  6.     </UniqueConstraint>
  7.   </And>
  8. </Logic>

In this command combination of Line1 and Line2 must be unique in the contact`s address collection.

Validating collection

When there is a collection and a rule needs to be applied on each of the collection`s element, ForEach can be used. This command will execute all its child rules against every element of the collection.

  1. <Logic name="allAddressLine1_NotNullEmpty">
  2.   <And>
  3.     <ForEach childName="c">
  4.       <Null value="c.Line1" negate="true"/>
  5.       <Empty value="c.Line1" negate="true"/>
  6.     </ForEach>
  7.   </And>
  8. </Logic>

childName will be the collection`s element reference for all the rules inside the ForEach

Minimum element of collection

One of the rules in here is that a contact must have at least one address. To define this rule we can check Count property of the collection by using Check.

We are going to add this rule to the logic named allAddressLine1_NotNullEmpty:

  1. <Logic name="allAddressLine1_NotNullEmpty">
  2.   <And>
  3.     <!-- Minimum an address must exists -->
  4.     <Check value="Count>0"/>
  5.  
  6.     <!-- Line1 of address can not be null or empty -->
  7.     <ForEach childName="c">
  8.       <Null value="c.Line1" negate="true"/>
  9.       <Empty value="c.Line1" negate="true"/>
  10.     </ForEach>
  11.   </And>
  12. </Logic>

Putting all together

What is left now, adding these two extra logic into validation rule and call them via contract logic.

  1. <Logic name="Contact">
  2.   <And>
  3.     <Or>
  4.       <Validate logic="ValidatePersonContact">
  5.         <When>
  6.           <And>
  7.             <Contains value="Family"/>
  8.             <Contains value="Title"/>
  9.           </And>
  10.         </When>
  11.       </Validate>
  12.       <Validate logic="ValidateCompanyContact">
  13.         <When>
  14.           <And>
  15.             <Contains value="BusinessNumber"/>
  16.           </And>
  17.         </When>
  18.       </Validate>
  19.     </Or>
  20.  
  21.     <Validate logic="allAddressLine1_NotNullEmpty" value="Addresses"/>
  22.     <Validate logic="allAddressLine1_UniqueConstraint" value="Addresses"/>
  23.   </And>
  24. </Logic>

However we need to put all the current logic of Contract into a And operator to get the aggregated result back when it is called.

Final rule

  1. <Validation name="ContactRule">
  2.   <Logic name="Contact">
  3.     <And>
  4.       <Or>
  5.         <Validate logic="ValidatePersonContact">
  6.           <When>
  7.             <And>
  8.               <Contains value="Family"/>
  9.               <Contains value="Title"/>
  10.             </And>
  11.           </When>
  12.         </Validate>
  13.         <Validate logic="ValidateCompanyContact">
  14.           <When>
  15.             <And>
  16.               <Contains value="BusinessNumber"/>
  17.             </And>
  18.           </When>
  19.         </Validate>
  20.       </Or>
  21.  
  22.       <Validate logic="allAddressLine1_NotNullEmpty" value="Addresses"/>
  23.       <Validate logic="allAddressLine1_UniqueConstraint" value="Addresses"/>
  24.     </And>
  25.   </Logic>
  26.  
  27.   <Logic name="Person">
  28.     <Or negate="true">
  29.       <Validate logic="ValidString" value="Name"/>
  30.       <Validate logic="ValidString" value="Email"/>
  31.     </Or>
  32.   </Logic>
  33.  
  34.   <Logic name="Company">
  35.     <Or negate="true">
  36.       <Validate logic="ValidString" value="Name"/>
  37.       <Validate logic="ValidString" value="Email"/>
  38.       <Validate logic="ValidString" value="BusinessNumber"/>
  39.     </Or>
  40.   </Logic>
  41.  
  42.   <Logic name="ValidString" variable="str">
  43.     <And>
  44.       <Null value="str" />
  45.       <Empty value="str" />
  46.     </And>
  47.   </Logic>
  48.   <Logic name="allAddressLine1_NotNullEmpty">
  49.     <And>
  50.       <!-- Minimum an address must exists -->
  51.       <Check value="Count>0"/>
  52.  
  53.       <!-- Line1 of address can not be null or empty -->
  54.       <ForEach childName="c">
  55.         <Null value="c.Line1" negate="true"/>
  56.         <Empty value="c.Line1" negate="true"/>
  57.       </ForEach>
  58.     </And>
  59.   </Logic>
  60.   <Logic name="allAddressLine1_UniqueConstraint">
  61.     <And>
  62.       <UniqueConstraint>
  63.         <Add property="Line1"/>
  64.         <Add property="Line2"/>
  65.       </UniqueConstraint>
  66.     </And>
  67.   </Logic>
  68. </Validation>

Next sections

In the next couple of articles we will cover different aspect of modelling and executing the validation rules using Validation logic.

  1. Introduction to validation rules
  2. Validating hierarchy (Inheritance relation)
  3. Validating association (Aggregation, Composition)
  4. Validation rule execution and collecting results
  5. Pass extra input values to validation rules
  6. Extending validation conditions and actions
  7. How to apply rules under some conditions
  8. Referencing commonly used logic
  9. Sample for Order processing validation logic