aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/thedevstack/conversationsplus/enums/MessageStatus.java
blob: 8a31a325eb2e515ac18e44eba84f5055434df1ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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<MessageStatus> validNextStates;
    private HashMap<MessageDirection, List<MessageStatus>> 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
    }
}