# $Id: s.ChainOfResponsibility.xotcl 1.10 01/03/23 21:55:33+01:00 neumann@somewhere.wu-wien.ac.at $
package provide xotcl::pattern::chainOfResponsibility 0.9

Class ChainOfResponsibility -superclass Class

ChainOfResponsibility instproc chainingFilter args {
  set cp [self calledproc]
  set rc [self regclass]
  #puts stderr "CHAIN [array names [self regclass]::chainedOperations ]---$cp"
  if {[$rc exists chainedOperations($cp)]} {
    #
    # a value is found on the chain, if it differs from the failure value !
    #
    set failureValue [$rc set chainedOperations($cp)]
    set r [[self] $cp $args]
    if {$r == $failureValue} {
      if {[[self] exists successor] &&
	  [set s [[self] set successor]] != ""} {
	#puts stderr "CHAIN: forwarding to $s"
	set r [$s $cp $args]
      }
    }
    set r ;# return $r
  } else {
    next ;# return [next]
  }
}

ChainOfResponsibility instproc init args {
  [self] filterappend ChainOfResponsibility::chainingFilter
  [self] parameter {successor}
  # chained operations hold their value of failure
  [self] array set chainedOperations {}
}

ChainOfResponsibility instproc addChainedOperation {name {failureValue ""}} {
  [self] set chainedOperations($name) $failureValue
}

ChainOfResponsibility instproc removeChainedOperation {name} {
  [self] unset chainedOperations($name)
}