package de.thedevstack.conversationsplus.enums; import java.util.Arrays; import java.util.HashMap; import java.util.List; /** */ public enum MessageStatus { WAITING, TRANSMITTING, TRANSMITTED, FAILED, CANCELED, DISPLAYED, RECEIVED; static { /* * Initialization of valid next states in this block, * because the enum values need to be known at initialization. * If trying to initialize in Constructor, then only forward transitions are possible., * no way to handle jumping back. */ WAITING.initValidNextStates(TRANSMITTING); TRANSMITTING.initValidNextStates(FAILED, TRANSMITTED, CANCELED); CANCELED.initValidNextStates(WAITING); FAILED.initValidNextStates(WAITING); // Restrict some transitions to be only valid for outgoing messages TRANSMITTED.initValidNextStatesForDirection(MessageDirection.OUT, RECEIVED, DISPLAYED); RECEIVED.initValidNextStatesForDirection(MessageDirection.OUT, DISPLAYED); } private List validNextStates; private HashMap> directionRestricted = new HashMap<>(); private void initValidNextStates(MessageStatus... validNextStates) { this.validNextStates = Arrays.asList(validNextStates); } private void initValidNextStatesForDirection(MessageDirection direction, MessageStatus... newStatus) { this.directionRestricted.put(direction, Arrays.asList(newStatus)); } public boolean isTransitionToStateAllowed(MessageStatus newStatus, MessageDirection direction) { boolean hasNoValidNextStates = this.validNextStates.isEmpty() && (!this.directionRestricted.containsKey(direction) || this.directionRestricted.get(direction).isEmpty()); boolean isValidNextState = this.validNextStates.contains(newStatus); boolean isValidNextStateForDirection = (this.directionRestricted.containsKey(direction) && this.directionRestricted.get(direction).contains(newStatus)); return hasNoValidNextStates // no valid next states -> every new state is allowed || isValidNextState // if newStatus is conditionless || isValidNextStateForDirection; // if the newStatus is valid for the direction } }