关系生命周期
@StateMachine
static interface ContractLifecycle {
@StateSet
static interface States {
@Initial
@Functions({ @Function(transition = ContractLifecycle.Transitions.Activate.class, value = Active.class),
@Function(transition = ContractLifecycle.Transitions.Cancel.class, value = Canceled.class) })
static interface Draft {}
@Functions({ @Function(transition = ContractLifecycle.Transitions.Expire.class, value = Expired.class),
@Function(transition = ContractLifecycle.Transitions.Cancel.class, value = Canceled.class) })
static interface Active {}
@End
static interface Expired {}
@End
static interface Canceled {}
}
@TransitionSet
static interface Transitions {
static interface Activate {}
static interface Expire {}
static interface Cancel {}
}
}
@LifecycleMeta(ContractLifecycle.class)
public static class Contract extends ReactiveObject {
public Contract() {
initialState(ContractLifecycle.States.Draft.class.getSimpleName());
}
@Transition
public void activate() {}
@Transition
public void expire() {}
@Transition
public void cancel() {}
}
// ///
// Relational Case 1.
// ///
@StateMachine
static interface RelationalOrderLifecycleSharingValidWhile {
@StateSet
static interface States {
@Initial
@Function(transition = Transitions.Start.class, value = Started.class)
@ValidWhile(on = { ContractLifecycle.States.Active.class }, relation = Relations.Contract.class)
static interface Created {}
@CompositeState
@Function(transition = Transitions.Cancel.class, value = Canceled.class)
static interface Started {
@StateSet
static interface SubStates {
@Initial
@Function(transition = RelationalOrderLifecycleSharingValidWhile.States.Started.SubTransitions.DoProduce.class, value = Producing.class)
@ValidWhile(on = { ContractLifecycle.States.Active.class }, relation = RelationalOrderLifecycleSharingValidWhile.Relations.Contract.class)
static interface OrderCreated {}
@Function(transition = RelationalOrderLifecycleSharingValidWhile.States.Started.SubTransitions.DoDeliver.class, value = Delivering.class)
@ValidWhile(on = { ContractLifecycle.States.Active.class }, relation = RelationalOrderLifecycleSharingValidWhile.Relations.Contract.class)
static interface Producing {}
@Function(transition = RelationalOrderLifecycleSharingValidWhile.States.Started.SubTransitions.ConfirmComplete.class, value = Done.class)
@ValidWhile(on = { ContractLifecycle.States.Active.class }, relation = RelationalOrderLifecycleSharingValidWhile.Relations.Contract.class)
static interface Delivering {}
@End
@ShortCut(RelationalOrderLifecycleSharingValidWhile.States.Finished.class)
// Ignoring : @ValidWhile(on = {
// ContractLifecycle.States.Active.class }, relation =
// Relations.Contract.class)
static interface Done {}
}
@TransitionSet
static interface SubTransitions {
static interface DoProduce {}
static interface DoDeliver {}
static interface ConfirmComplete {}
}
}
@End
static interface Finished {}
@End
static interface Canceled {}
}
@TransitionSet
static interface Transitions {
static interface Start {}
static interface Cancel {}
}
@RelationSet
static interface Relations {
@RelateTo(ContractLifecycle.class)
static interface Contract {}
}
}
@LifecycleMeta(RelationalOrderLifecycleSharingValidWhile.class)
public static class ProductOrderSharingValidWhile extends ProductBase {
private Contract contract;
public ProductOrderSharingValidWhile(Contract contract) {
this.contract = contract;
initialState(RelationalOrderLifecycleSharingValidWhile.States.Created.class.getSimpleName());
}
@Relation(RelationalOrderLifecycleSharingValidWhile.Relations.Contract.class)
public Contract getContract() {
return this.contract;
}
@Transition
public void start() {}
@Transition
public void cancel() {}
@Transition
public void doProduce() {}
@Transition
public void doDeliver() {}
@Transition
public void confirmComplete() {}
}
@Test
public void test_relational_composite_state_machine_sharing_with_composite_state() {
final Contract contract = new Contract();
// Outer Initial State
assertState(ContractLifecycle.States.Draft.class, contract);
contract.activate();
assertState(ContractLifecycle.States.Active.class, contract);
final ProductOrderSharingValidWhile product = new ProductOrderSharingValidWhile(contract);
// Outer State + Outer Transition => Composite State => Composite
// Initial State
{
// Outer Initial State
assertState(RelationalOrderLifecycleSharingValidWhile.States.Created.class, product);
// Outer Transition
product.start();
assertState(RelationalOrderLifecycleSharingValidWhile.States.Started.SubStates.OrderCreated.class, product);
}
{
// Composite State + Composite Transition => Composite State
product.doProduce();
assertState(RelationalOrderLifecycleSharingValidWhile.States.Started.SubStates.Producing.class, product);
product.doDeliver();
assertState(RelationalOrderLifecycleSharingValidWhile.States.Started.SubStates.Delivering.class, product);
}
{
// Composite State + Composite Transition => Composite Final State
// => Outer State
product.confirmComplete();
assertState(RelationalOrderLifecycleSharingValidWhile.States.Finished.class, product);
}
}
@Test(expected = LifecycleException.class)
public void test_relational_standalone_composite_invalid_state_sharing_from_owning_valid_while() {
final Contract contract = new Contract();
assertState(ContractLifecycle.States.Draft.class, contract);
final ProductOrderSharingValidWhile order = new ProductOrderSharingValidWhile(contract);
try {
order.start();
} catch (LifecycleException e) {
assertInvalidStateErrorByValidWhile(e, contract, order, ContractLifecycle.States.Active.class);
}
contract.activate();
assertState(ContractLifecycle.States.Active.class, contract);
order.start();
assertState(RelationalOrderLifecycleSharingValidWhile.States.Started.SubStates.OrderCreated.class, order);
contract.cancel();
assertState(ContractLifecycle.States.Canceled.class, contract);
try {
order.doProduce();
} catch (LifecycleException e) {
assertInvalidStateErrorByValidWhile(e, contract, order, ContractLifecycle.States.Active.class);
throw e;
}
}