@StateMachine static interface InformativeStateMachine { @StateSet static interface States { @Initial @Functions({ @Function(transition = Transitions.LogicalDelete.class, value = Recycled.class), @Function(transition = Transitions.Confirm.class, value = Confirmed.class) }) static interface Draft {} @Function(transition = Transitions.Finish.class, value = Finished.class) static interface Confirmed {} @End static interface Finished {} @Functions({ @Function(transition = Transitions.PutBack.class, value = Draft.class), @Function(transition = Transitions.PhysicalDelete.class, value = Vanished.class) }) static interface Recycled {} @End static interface Vanished {} } @TransitionSet static interface Transitions { static interface Confirm {} static interface LogicalDelete {} static interface PutBack {} static interface PhysicalDelete {} static interface File {} static interface Finish {} } } @StateMachine static interface CustomerStateMachine extends InformativeStateMachine { @StateSet static interface States extends InformativeStateMachine.States { @CompositeState @LifecycleOverride static interface Confirmed extends InformativeStateMachine.States.Confirmed { @StateSet static interface ConfirmedStates { @Initial @Functions({ @Function(transition = Transitions.Suspend.class, value = ServiceSuspended.class), @Function(transition = Transitions.TerminateService.class, value = ServiceExpired.class), @Function(transition = Transitions.Cancel.class, value = Canceled.class) }) static interface InService {} @Function(transition = Transitions.Resume.class, value = InService.class) static interface ServiceSuspended {} @Functions({ @Function(transition = Transitions.Renew.class, value = InService.class), @Function(transition = Transitions.Disconnect.class, value = Disconnected.class), @Function(transition = Transitions.Abandon.class, value = Abandoned.class) }) static interface ServiceExpired {} @Functions({ @Function(transition = Transitions.Abandon.class, value = Abandoned.class), @Function(transition = Transitions.Disconnect.class, value = Disconnected.class) }) static interface Canceled {} @End @ShortCut(InformativeStateMachine.States.Finished.class) static interface Disconnected {} @End @ShortCut(InformativeStateMachine.States.Recycled.class) static interface Abandoned {} } @TransitionSet static interface Transitions { static interface Abandon {} static interface Suspend {} static interface Resume {} static interface Renew {} static interface Cancel {} static interface TerminateService {} static interface Disconnect {} } } } } @StateMachine static interface ContractStateMachine extends InformativeStateMachine { @StateSet static interface States extends InformativeStateMachine.States { @CompositeState @LifecycleOverride static interface Confirmed extends InformativeStateMachine.States.Confirmed { @StateSet static interface ConfirmedStates { @Initial @Functions({ @Function(transition = Transitions.StartService.class, value = ServiceStarted.class), @Function(transition = Transitions.TerminateService.class, value = Terminated.class) }) @InboundWhile(on = { InformativeStateMachine.States.Draft.class, CustomerStateMachine.States.Confirmed.ConfirmedStates.InService.class }, relation = Relations.Customer.class) @ValidWhile(on = { CustomerStateMachine.States.Confirmed.ConfirmedStates.InService.class }, relation = Relations.Customer.class) static interface Effective {} @Function(transition = Transitions.AbortService.class, value = ServiceAborted.class) @ValidWhile(on = { CustomerStateMachine.States.Confirmed.ConfirmedStates.InService.class }, relation = Relations.Customer.class) @InboundWhile(on = { CustomerStateMachine.States.Confirmed.ConfirmedStates.InService.class }, relation = Relations.Customer.class) static interface ServiceStarted {} @Function(transition = Transitions.Invalidate.class, value = Uneffective.class) @InboundWhile(on = { CustomerStateMachine.States.Confirmed.ConfirmedStates.InService.class }, relation = Relations.Customer.class) static interface ServiceAborted {} @End @ShortCut(InformativeStateMachine.States.Finished.class) static interface Terminated {} @End @ShortCut(InformativeStateMachine.States.Draft.class) static interface Uneffective {} } @TransitionSet static interface Transitions { static interface Invalidate {} static interface StartService {} static interface AbortService {} static interface TerminateService {} } @RelationSet static interface Relations { @Parent @RelateTo(CustomerStateMachine.class) static interface Customer {} } } } } @StateMachine static interface OrderStateMachine extends InformativeStateMachine { @StateSet static interface States extends InformativeStateMachine.States { @CompositeState @LifecycleOverride static interface Confirmed extends InformativeStateMachine.States.Confirmed { @StateSet static interface ConfirmedStates { @Initial @InboundWhile(on = { ContractStateMachine.States.Confirmed.ConfirmedStates.ServiceStarted.class }, relation = Relations.Contract.class) @ValidWhile(on = { ContractStateMachine.States.Confirmed.ConfirmedStates.ServiceStarted.class }, relation = Relations.Contract.class) @Functions({ @Function(transition = Transitions.StartProduce.class, value = Manufactoring.class), @Function(transition = Transitions.Dequeue.class, value = Dequeued.class) }) static interface Queued {} @InboundWhiles({ @InboundWhile(on = { ContractStateMachine.States.Confirmed.ConfirmedStates.ServiceStarted.class }, relation = Relations.Contract.class), @InboundWhile(on = { ResourceStateMachine.States.OfficialRunning.RunningStates.Idle.class }, relation = Relations.Resource.class) }) @ValidWhiles({ @ValidWhile(on = { ContractStateMachine.States.Confirmed.ConfirmedStates.ServiceStarted.class }, relation = Relations.Contract.class) }) @Function(transition = Transitions.StartPackage.class, value = Packaging.class) static interface Manufactoring {} @InboundWhile(on = { ContractStateMachine.States.Confirmed.ConfirmedStates.ServiceStarted.class }, relation = Relations.Contract.class) @ValidWhile(on = { ContractStateMachine.States.Confirmed.ConfirmedStates.ServiceStarted.class }, relation = Relations.Contract.class) @Function(transition = Transitions.Deliver.class, value = { Delivering.class }) static interface Packaging {} @InboundWhile(on = { ContractStateMachine.States.Confirmed.ConfirmedStates.ServiceStarted.class }, relation = Relations.Contract.class) @ValidWhile(on = { ContractStateMachine.States.Confirmed.ConfirmedStates.ServiceStarted.class }, relation = Relations.Contract.class) @Function(transition = Transitions.Complete.class, value = Completed.class) static interface Delivering {} @End @ShortCut(InformativeStateMachine.States.Finished.class) static interface Completed {} @End @ShortCut(InformativeStateMachine.States.Draft.class) static interface Dequeued {} } @TransitionSet static interface Transitions { static interface Deliver {} static interface Dequeue {} static interface StartProduce {} static interface StartPackage {} static interface Complete {} } @RelationSet static interface Relations { @Parent @RelateTo(ContractStateMachine.class) static interface Contract {} @RelateTo(ResourceStateMachine.class) static interface Resource {} } } } } @StateMachine static interface ResourceStateMachine { @StateSet static interface States { @Initial @Function(transition = Transitions.Test.class, value = TestRunning.class) static interface New {} @Functions({ @Function(transition = Transitions.GoLive.class, value = OfficialRunning.class), @Function(transition = Transitions.ConfirmMalfunction.class, value = Malfunctioning.class) }) static interface TestRunning {} @Functions({ @Function(transition = Transitions.Repair.class, value = Repairing.class), @Function(transition = Transitions.Deprecate.class, value = Deprecated.class) }) static interface Malfunctioning {} @Function(transition = Transitions.ConfirmMalfunction.class, value = Malfunctioning.class) @CompositeState static interface OfficialRunning { @StateSet static interface RunningStates { @Initial @Function(transition = RunningTransitions.Acquire.class, value = Busy.class) static interface Idle {} @Functions({ @Function(transition = RunningTransitions.Fail.class, value = Failing.class), @Function(transition = RunningTransitions.Release.class, value = Idle.class) }) static interface Busy {} @End @ShortCut(Malfunctioning.class) static interface Failing {} } @TransitionSet static interface RunningTransitions { static interface Acquire {} static interface Release {} static interface Fail {} } } @Function(transition = Transitions.Test.class, value = TestRunning.class) static interface Repairing {} @End static interface Deprecated {} } @TransitionSet static interface Transitions { static interface Test {} static interface ConfirmMalfunction {} static interface Repair {} static interface GoLive {} static interface Deprecate {} } } @LifecycleMeta(InformativeStateMachine.class) @LifecycleLock(SimpleLock.class) static class InformativeObject extends ReactiveObject { public InformativeObject() { initialState(InformativeStateMachine.States.Draft.class.getSimpleName()); } @Transition public void confirm() {} @Transition public void logicalDelete() {} @Transition public void putBack() {} @Transition public void physicalDelete() {} @Transition public void file() {} @Transition public void finish() {} } @LifecycleMeta(CustomerStateMachine.class) @LifecycleLock(SimpleLock.class) static class CustomerObject extends InformativeObject { @Transition public void abandon() {} @Transition public void suspend() {} @Transition public void resume() {} @Transition public void renew() {} @Transition public void cancel() {} @Transition public void terminateService() {} @Transition public void disconnect() {} } @LifecycleMeta(ContractStateMachine.class) @LifecycleLock(SimpleLock.class) static class ContractObject extends InformativeObject { @Relation(ContractStateMachine.States.Confirmed.Relations.Customer.class) private CustomerObject customer; public ContractObject(final CustomerObject customer) { super(); this.customer = customer; } @Transition public void invalidate() {} @Transition public void startService() {} @Transition public void abortService() {} @Transition public void terminateService() {} } @LifecycleMeta(OrderStateMachine.class) @LifecycleLock(SimpleLock.class) static class OrderObject extends InformativeObject { @Relation private ContractObject contract; public OrderObject(ContractObject contract) { this.contract = contract; } @Transition public void deliver() {} @Transition public void dequeue() {} @Transition public void startProduce(@Relation(OrderStateMachine.States.Confirmed.Relations.Resource.class) ResourceObject resource) {} @Transition public void startPackage() {} @Transition public void complete() {} } @LifecycleMeta(ResourceStateMachine.class) @LifecycleLock(SimpleLock.class) static class ResourceObject extends ReactiveObject { public ResourceObject() { initialState(ResourceStateMachine.States.New.class.getName()); } @Transition public void test() {} @Transition public void confirmMalfunction() {} @Transition public void repair() {} @Transition public void goLive() {} @Transition public void deprecate() {} @Transition public void acquire() {} @Transition public void release() {} @Transition public void fail() {} }
@Test public void test_relational_locking() { final CustomerObject customer = new CustomerObject(); final ContractObject contract = new ContractObject(customer); final OrderObject order = new OrderObject(contract); final ResourceObject resource = new ResourceObject(); customer.confirm(); contract.confirm(); contract.startService(); order.confirm(); resource.test(); resource.goLive(); order.startProduce(resource); order.startPackage(); order.deliver(); order.complete(); assertState(OrderStateMachine.States.Finished.class, order); }
带有关系约束的状态机引擎执行过程中读写锁的使用日志