cybertools/stateful
helmutm c0c772ff30 extend 'stateful' implementation (sort of a very simple workflow system)
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1933 fd906abe-77d9-0310-91a1-e0d9ade77398
2007-08-19 14:41:23 +00:00
..
__init__.py added simple 'stateful' (sort of mini-workflow) package 2007-01-04 11:11:32 +00:00
base.py extend 'stateful' implementation (sort of a very simple workflow system) 2007-08-19 14:41:23 +00:00
definition.py extend 'stateful' implementation (sort of a very simple workflow system) 2007-08-19 14:41:23 +00:00
interfaces.py extend 'stateful' implementation (sort of a very simple workflow system) 2007-08-19 14:41:23 +00:00
README.txt extend 'stateful' implementation (sort of a very simple workflow system) 2007-08-19 14:41:23 +00:00
tests.py added simple 'stateful' (sort of mini-workflow) package 2007-01-04 11:11:32 +00:00

================
Stateful Objects
================

  ($Id$)

  >>> from cybertools.stateful.definition import StatesDefinition
  >>> from cybertools.stateful.definition import State, Transition
  >>> from cybertools.stateful.definition import registerStatesDefinition
  >>> from cybertools.stateful.base import Stateful

We start with a simple demonstration class that provides stateful
behaviour directly.

  >>> class Demo(Stateful):
  ...     pass

  >>> demo = Demo()

The default states definition has the `started` state has its initial
state.

  >>> demo.getState()
  'started'
  >>> demo.getStateObject().title
  'Started'

We can now execute the `finish` Transition.

  >>> demo.doTransition('finish')
  >>> demo.getState()
  'finished'

More complex states definitions
-------------------------------

  >>> registerStatesDefinition(
  ...     StatesDefinition('publishing',
  ...         State('private', 'private', ('show',)),
  ...         State('visible', 'visible', ('publish', 'hide',)),
  ...         State('published', 'published', ('retract',)),
  ...         Transition('show', 'show', 'visible'),
  ...         Transition('hide', 'hide', 'private'),
  ...         Transition('publish', 'publish', 'published'),
  ...         Transition('retract', 'retract', 'visible'),
  ...         initialState='visible'))

  >>> demo = Demo()
  >>> demo.statesDefinition = 'publishing'
  >>> demo.getState()
  'visible'

If we try to execute a transition that is not an outgoing transition
of the current state we get an error.

  >>> demo.doTransition('retract')
  Traceback (most recent call last):
  ...
  ValueError: Transition 'retract' is not reachable from state 'visible'.
  >>> demo.getState()
  'visible'


Stateful Adapters
=================

Objects that show stateful behaviour need not be derived from the Stateful
class, for persistent objects one can also provide a stateful adapter.

  >>> from persistent import Persistent
  >>> class Demo(Persistent):
  ...     pass

  >>> demo = Demo()

  >>> from zope import component
  >>> from cybertools.stateful.base import StatefulAdapter
  >>> component.provideAdapter(StatefulAdapter)

We can now retrieve a stateful adapter using the IStateful interface.

  >>> from cybertools.stateful.interfaces import IStateful

  >>> statefulDemo = IStateful(demo)
  >>> statefulDemo.getState()
  'started'
  >>> statefulDemo.getStateObject().title
  'Started'

  >>> statefulDemo.doTransition('finish')
  >>> statefulDemo.getState()
  'finished'

If we make a new adapter for the same persistent object we get
back the state that is stored with the object.

  >>> statefulDemo = IStateful(demo)
  >>> statefulDemo.getState()
  'finished'