/** * The incorporate method uses a simple state machine for an order's status to generate * the current state of an order using event sourcing and aggregation. * <p> * The event diagram below represents how events are incorporated into generating the * order status. The event log for the order status can be used to rollback the state * of the order in the case of a failed distributed transaction. * <p> * Events: +<--PURCHASED+ +<--CREATED+ +<---ORDERED+ +<----SHIPPED+ * * | | | | | | | | * Status +PURCHASED---+PENDING------+CONFIRMED-----+SHIPPED--------+DELIVERED * * | | | | | | | | * Events: +CREATED---->+ +ORDERED-->+ +SHIPPED--->+ +DELIVERED-->+ * * @param orderEvent is the event to incorporate into the state machine * @return the aggregate {@link Order} with the aggregated order status */publicOrderincorporate(OrderEventorderEvent) {
if (orderStatus == null)
orderStatus = OrderStatus.PURCHASED;
switch (orderStatus) {
casePURCHASED:
if (orderEvent.getType() == OrderEventType.CREATED)
orderStatus = OrderStatus.PENDING;
break;
casePENDING:
if (orderEvent.getType() == OrderEventType.ORDERED) {
orderStatus = OrderStatus.CONFIRMED;
} elseif (orderEvent.getType() == OrderEventType.PURCHASED) {
orderStatus = OrderStatus.PURCHASED;
}
break;
caseCONFIRMED:
if (orderEvent.getType() == OrderEventType.SHIPPED) {
orderStatus = OrderStatus.SHIPPED;
} elseif (orderEvent.getType() == OrderEventType.CREATED) {
orderStatus = OrderStatus.PENDING;
}
break;
caseSHIPPED:
if (orderEvent.getType() == OrderEventType.DELIVERED) {
orderStatus = OrderStatus.DELIVERED;
} elseif (orderEvent.getType() == OrderEventType.ORDERED) {
orderStatus = OrderStatus.CONFIRMED;
}
break;
caseDELIVERED:
if (orderEvent.getType() == OrderEventType.SHIPPED)
orderStatus = OrderStatus.SHIPPED;
break;
default:
// Invalid event type with regards to the order statusbreak;
}
returnthis;
}