statemachines.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. # -*- coding: utf-8 -*-
  2. #!/usr/bin/env python
  3. class StateViolationError(RuntimeError):
  4. pass
  5. class WithdrawState(object):
  6. def new_state(self, state):
  7. self.__class__ = state
  8. def confirm(self):
  9. raise NotImplementedError()
  10. def process(self):
  11. raise NotImplementedError()
  12. def revoke(self):
  13. raise NotImplementedError()
  14. def succeed(self):
  15. raise NotImplementedError()
  16. def fail(self):
  17. raise NotImplementedError()
  18. class WithdrawConfirmedState(WithdrawState):
  19. def confirm(self):
  20. raise StateViolationError('system already confirmed withdraw application')
  21. def process(self):
  22. raise self.new_state(WithdrawProcessingState)
  23. def revoke(self):
  24. raise StateViolationError('the withdraw application needs to be processed first')
  25. def succeed(self):
  26. raise StateViolationError('the withdraw application needs to be processed first')
  27. def fail(self):
  28. raise StateViolationError('the withdraw application needs to be processed first')
  29. class WithdrawProcessingState(WithdrawState):
  30. def confirm(self):
  31. raise StateViolationError('system already confirmed the withdraw application.')
  32. def process(self):
  33. raise StateViolationError('system is already processing the withdraw application')
  34. def revoke(self):
  35. self.new_state(WithdrawRevokedState)
  36. def succeed(self):
  37. self.new_state(WithdrawSucceededState)
  38. def fail(self):
  39. self.new_state(WithdrawFailedState)
  40. class WithdrawRevokedState(WithdrawState):
  41. def confirm(self):
  42. raise StateViolationError('system already confirmed the withdraw application.')
  43. def process(self):
  44. self.new_state(WithdrawProcessingState)
  45. def revoke(self):
  46. raise StateViolationError('the withdraw application has already been revoked.')
  47. def succeed(self):
  48. self.new_state(WithdrawSucceededState)
  49. def fail(self):
  50. self.new_state(WithdrawFailedState)
  51. class WithdrawSucceededState(WithdrawState):
  52. def confirm(self):
  53. raise StateViolationError('system already confirmed withdraw application.')
  54. def process(self):
  55. raise StateViolationError('system cannot process a succeeded withdraw application.')
  56. def revoke(self):
  57. raise StateViolationError('cannot withdraw a succeeded withdraw application.')
  58. def succeed(self):
  59. raise StateViolationError('the withdraw has already succeeded.')
  60. def fail(self):
  61. raise StateViolationError('cannot fail a succeeded withdraw application.')
  62. class WithdrawFailedState(WithdrawState):
  63. def confirm(self):
  64. raise StateViolationError('system already confirmed withdraw application')
  65. def process(self):
  66. raise StateViolationError('system cannot process a failed withdraw application')
  67. def revoke(self):
  68. raise StateViolationError('cannot withdraw a failed withdraw application.')
  69. def succeed(self):
  70. raise StateViolationError('cannot fail a succeeded withdraw application.')
  71. def fail(self):
  72. raise StateViolationError('the withdraw has already succeeded.')
  73. class Connection:
  74. def __init__(self):
  75. self.new_state(ClosedConnection)
  76. def new_state(self, newstate):
  77. self.__class__ = newstate
  78. def read(self):
  79. raise NotImplementedError()
  80. def write(self, data):
  81. raise NotImplementedError()
  82. def open(self):
  83. raise NotImplementedError()
  84. def close(self):
  85. raise NotImplementedError()
  86. class ClosedConnection(Connection):
  87. def read(self):
  88. raise RuntimeError('Not open')
  89. def write(self, data):
  90. raise RuntimeError('Not open')
  91. def open(self):
  92. self.new_state(OpenConnection)
  93. def close(self):
  94. raise RuntimeError('Already closed')
  95. class OpenConnection(Connection):
  96. def read(self):
  97. print 'reading'
  98. def write(self, data):
  99. print 'writing'
  100. def open(self):
  101. raise RuntimeError('Already open')
  102. def close(self):
  103. self.new_state(ClosedConnection)
  104. __all__ = ["WithdrawConfirmedState", "WithdrawProcessingState", "WithdrawRevokedState",
  105. "WithdrawSucceededState", "WithdrawFailedState", "StateViolationError"]