package com.odelia.rules import groovy.beans.Bindable enum StatutCommande { EN_COURS, VALIDEE } class Commande { @Bindable StatutCommande statut = StatutCommande.EN_COURS @Bindable def commandeValidee def panier = [ [code: 1, label: 'Article A', prix: 10.0], [code: 2, label: 'Article B', prix: 21.0] ] as ObservableList def total def calculerSousTotal() { panier.prix.sum() } def calculerFraisDePort // algorithme variable } class Main { static void main(String[] args) { // Règle sans condition def rule = new Rule(action: { source -> 2*source }) assert rule.run(1) == 2 // Règle avec condition rule = new Rule(condition: { it > 2 }, action: { source -> 2*source }) assert rule.run(3) == 6 assert rule.run(1) == null assert rule.action(4) == 8 // Mixin dynamique Commande.mixin EventRuleSupport // Exemples de règles avec la classe Commande def commande = new Commande() rule = new Rule(action: { panier -> panier.prix.sum() }) assert rule.run(commande.panier) == 31 // Changement de calcul des frais de port rule = new Rule(action: { cmd -> cmd.calculerFraisDePort = { 5 + cmd.panier.size() *2 } }) rule.run(commande) assert commande.calculerFraisDePort() == 9 // Déclenchement du calcul du total lors du changement du statut de la // commande et si le nouveau statut est VALIDEE rule = new RuleListener( condition: { cmd -> cmd.statut == StatutCommande.VALIDEE }, action: { cmd -> cmd.with { total = calculerSousTotal() + calculerFraisDePort() } } ) commande.addPropertyChangeListener('statut', rule) // Ceci déclenche l'exécution de la règle de calcul du total commande.statut = StatutCommande.VALIDEE assert commande.total == 31 + 9 // On souhaite recalculer le total si le panier est modifié def cartRule = new RuleListener( action: { panier -> rule.run(commande) } ) commande.panier.addPropertyChangeListener(cartRule) commande.panier << [code: 3, label: 'Article C', prix: 5.0] assert commande.total == 36 + 11 // Ajout de règle depuis un script pouvant être externe def builder = new RuleListenerBuilder(commande) builder.addRules( """rule { sourceProperty = 'statut' condition = { true } action = { source -> println 'Salut depuis DSL ! Statut : ' + source.statut } } rule { sourceProperty = 'commandeValidee' condition = { true } action = { source -> println 'Evénement commandeValidee émis !' } }""") // Retrouver l'ensemble des méthodes contenant 'PropertyChange' // Commande.metaClass.methods.findAll { it.name.contains('PropertyChange') } // println Commande.metaClass.methods.findAll { it.name.contains('PropertyChange') }.each { println it } // Caluler le total automatiquement et émettre un événement commande.with { total = 0 statut = StatutCommande.EN_COURS // Supposons que le panier est modifié ici... statut = StatutCommande.VALIDEE // entraîne le calcul du total fireEvent('commandeValidee') assert commande.total == 36 + 11 } } }