Example usage for org.springframework.statemachine.support StateMachineUtils isSubstate

List of usage examples for org.springframework.statemachine.support StateMachineUtils isSubstate

Introduction

In this page you can find the example usage for org.springframework.statemachine.support StateMachineUtils isSubstate.

Prototype

public static <S, E> boolean isSubstate(State<S, E> left, State<S, E> right) 

Source Link

Document

Checks if right hand side is a substate of a left hand side.

Usage

From source file:org.springframework.statemachine.support.AbstractStateMachine.java

synchronized void setCurrentState(State<S, E> state, Message<E> message, Transition<S, E> transition,
        boolean exit, StateMachine<S, E> stateMachine, Collection<State<S, E>> sources,
        Collection<State<S, E>> targets) {
    State<S, E> findDeep = findDeepParent(state);
    boolean isTargetSubOf = false;
    if (transition != null) {
        isTargetSubOf = StateMachineUtils.isSubstate(state, transition.getSource());
        if (isTargetSubOf && currentState == transition.getTarget()) {
            state = transition.getSource();
        }/*from  www  .j ava2 s .  c  o m*/
    }

    boolean nonDeepStatePresent = false;

    if (states.contains(state)) {
        if (exit) {
            exitCurrentState(state, message, transition, stateMachine, sources, targets);
        }
        State<S, E> notifyFrom = currentState;
        currentState = state;
        if (!isRunning()) {
            start();
        }
        entryToState(state, message, transition, stateMachine);
        notifyStateChanged(buildStateContext(Stage.STATE_CHANGED, message, null, getRelayStateMachine(),
                notifyFrom, state));
        nonDeepStatePresent = true;
    } else if (currentState == null && StateMachineUtils.isSubstate(findDeep, state)) {
        if (exit) {
            exitCurrentState(findDeep, message, transition, stateMachine, sources, targets);
        }
        State<S, E> notifyFrom = currentState;
        currentState = findDeep;
        if (!isRunning()) {
            start();
        }
        entryToState(findDeep, message, transition, stateMachine);
        notifyStateChanged(buildStateContext(Stage.STATE_CHANGED, message, null, getRelayStateMachine(),
                notifyFrom, findDeep));
    }

    if (currentState != null && !nonDeepStatePresent) {
        if (findDeep != null) {
            if (exit) {
                exitCurrentState(state, message, transition, stateMachine, sources, targets);
            }
            if (currentState == findDeep) {

                if (currentState.isSubmachineState()) {
                    StateMachine<S, E> submachine = ((AbstractState<S, E>) currentState).getSubmachine();
                    // need to check complete as submachine may now return non null
                    if (!submachine.isComplete() && submachine.getState() == state) {
                        if (currentState == findDeep) {
                            if (isTargetSubOf) {
                                entryToState(currentState, message, transition, stateMachine);
                            }
                            currentState = findDeep;
                            ((AbstractStateMachine<S, E>) submachine).setCurrentState(state, message,
                                    transition, false, stateMachine);
                            return;
                        }
                    }
                } else if (currentState.isOrthogonal()) {
                    Collection<Region<S, E>> regions = ((AbstractState<S, E>) currentState).getRegions();
                    for (Region<S, E> region : regions) {
                        if (region.getState() == state) {
                            if (currentState == findDeep) {
                                if (isTargetSubOf) {
                                    entryToState(currentState, message, transition, stateMachine);
                                }
                                currentState = findDeep;
                                ((AbstractStateMachine<S, E>) region).setCurrentState(state, message,
                                        transition, false, stateMachine);
                                return;
                            }
                        }

                    }
                }
            }
            boolean shouldTryEntry = findDeep != currentState;
            if (!shouldTryEntry && (transition.getSource() == currentState
                    && StateMachineUtils.isSubstate(currentState, transition.getTarget()))) {
                shouldTryEntry = true;
            }
            currentState = findDeep;
            if (shouldTryEntry) {
                entryToState(currentState, message, transition, stateMachine, sources, targets);
            }

            if (currentState.isSubmachineState()) {
                StateMachine<S, E> submachine = ((AbstractState<S, E>) currentState).getSubmachine();
                ((AbstractStateMachine<S, E>) submachine).setCurrentState(state, message, transition, false,
                        stateMachine);
            } else if (currentState.isOrthogonal()) {
                Collection<Region<S, E>> regions = ((AbstractState<S, E>) currentState).getRegions();
                for (Region<S, E> region : regions) {
                    ((AbstractStateMachine<S, E>) region).setCurrentState(state, message, transition, false,
                            stateMachine);
                }
            }
        }
    }
    if (history != null && transition.getKind() != TransitionKind.INITIAL) {
        // do not set history if this is initial transition as
        // it would break history state set via reset as
        // we get here i.e. when machine is started in reset.
        // and it really doesn't make sense to set initial state for history
        // if we get here via initial transition
        if (history.getKind() == PseudoStateKind.HISTORY_SHALLOW) {
            ((HistoryPseudoState<S, E>) history).setState(findDeep);
        } else if (history.getKind() == PseudoStateKind.HISTORY_DEEP) {
            ((HistoryPseudoState<S, E>) history).setState(state);
        }
    }
    // if state was set from parent and we're now complete
    // also initiate stop
    if (stateMachine != this && isComplete()) {
        stop();
    }
}

From source file:org.springframework.statemachine.support.AbstractStateMachine.java

private void exitFromState(State<S, E> state, Message<E> message, Transition<S, E> transition,
        StateMachine<S, E> stateMachine, Collection<State<S, E>> sources, Collection<State<S, E>> targets) {
    if (state == null) {
        return;//w  w w .j av a  2s .c  om
    }
    log.trace("Trying Exit state=[" + state + "]");
    StateContext<S, E> stateContext = buildStateContext(Stage.STATE_EXIT, message, transition, stateMachine);

    if (transition != null) {

        State<S, E> findDeep = findDeepParent(transition.getTarget());
        boolean isTargetSubOfOtherState = findDeep != null && findDeep != currentState;
        boolean isSubOfSource = StateMachineUtils.isSubstate(transition.getSource(), currentState);
        boolean isSubOfTarget = StateMachineUtils.isSubstate(transition.getTarget(), currentState);

        if (transition.getKind() == TransitionKind.LOCAL
                && StateMachineUtils.isSubstate(transition.getSource(), transition.getTarget())
                && transition.getSource() == currentState) {
            return;
        } else if (transition.getKind() == TransitionKind.LOCAL
                && StateMachineUtils.isSubstate(transition.getTarget(), transition.getSource())
                && transition.getTarget() == currentState) {
            return;
        }

        // TODO: this and entry below should be done via a separate
        // voter of some sort which would reveal transition path
        // we could make a choice on.
        if (currentState == transition.getSource() && currentState == transition.getTarget()) {
        } else if (!isSubOfSource && !isSubOfTarget && currentState == transition.getSource()) {
        } else if (!isSubOfSource && !isSubOfTarget && currentState == transition.getTarget()) {
        } else if (isTargetSubOfOtherState) {
        } else if (!isSubOfSource && !isSubOfTarget && findDeep == null) {
        } else if (!isSubOfSource && !isSubOfTarget && (transition.getSource() == currentState
                && StateMachineUtils.isSubstate(currentState, transition.getTarget()))) {
        } else if (StateMachineUtils.isNormalPseudoState(transition.getTarget())) {
            if (isPseudoStateSubstate(findDeep, targets)) {
                return;
            }
        } else if (findDeep != null && findDeep != state && findDeep.getStates().contains(state)) {
        } else if (!isSubOfSource && !isSubOfTarget) {
            return;
        }

    }

    log.debug("Exit state=[" + state + "]");
    state.exit(stateContext);

    notifyStateExited(buildStateContext(Stage.STATE_EXIT, message, null, getRelayStateMachine(), state, null));
}

From source file:org.springframework.statemachine.support.AbstractStateMachine.java

private boolean isPseudoStateSubstate(State<S, E> left, Collection<State<S, E>> rights) {
    if (rights == null || left == null) {
        return false;
    }//from w ww  .j  a va 2 s  . c  o  m
    for (State<S, E> s : rights) {
        if (StateMachineUtils.isSubstate(left, s)) {
            return true;
        }
    }
    return false;
}

From source file:org.springframework.statemachine.support.AbstractStateMachine.java

private void entryToState(State<S, E> state, Message<E> message, Transition<S, E> transition,
        StateMachine<S, E> stateMachine, Collection<State<S, E>> sources, Collection<State<S, E>> targets) {
    if (state == null) {
        return;/*from w ww  . j  a  v  a2  s  . c om*/
    }
    log.trace("Trying Enter state=[" + state + "]");
    StateContext<S, E> stateContext = buildStateContext(Stage.STATE_ENTRY, message, transition, stateMachine,
            sources, targets);

    if (transition != null) {
        State<S, E> findDeep1 = findDeepParent(transition.getTarget());
        State<S, E> findDeep2 = findDeepParent(transition.getSource());
        boolean isComingFromOtherSubmachine = findDeep1 != null && findDeep2 != null
                && findDeep2 != currentState;

        boolean isSubOfSource = StateMachineUtils.isSubstate(transition.getSource(), currentState);
        boolean isSubOfTarget = StateMachineUtils.isSubstate(transition.getTarget(), currentState);

        if (transition.getKind() == TransitionKind.LOCAL
                && StateMachineUtils.isSubstate(transition.getSource(), transition.getTarget())
                && transition.getSource() == currentState) {
            return;
        } else if (transition.getKind() == TransitionKind.LOCAL
                && StateMachineUtils.isSubstate(transition.getTarget(), transition.getSource())
                && transition.getTarget() == currentState) {
            return;
        }

        if (currentState == transition.getSource() && currentState == transition.getTarget()) {
        } else if (!isSubOfSource && !isSubOfTarget && currentState == transition.getTarget()) {
        } else if (isComingFromOtherSubmachine) {
        } else if (!isSubOfSource && !isSubOfTarget && findDeep2 == null) {
        } else if (isSubOfSource && !isSubOfTarget && currentState == transition.getTarget()) {
            if (isDirectSubstate(transition.getSource(), transition.getTarget())
                    && transition.getKind() != TransitionKind.LOCAL && isInitial(transition.getTarget())) {
                return;
            }
        } else if (!isSubOfSource && !isSubOfTarget && (transition.getSource() == currentState
                && StateMachineUtils.isSubstate(currentState, transition.getTarget()))) {
        } else if (!isSubOfSource && !isSubOfTarget) {
            if (!StateMachineUtils.isTransientPseudoState(transition.getTarget())) {
                return;
            }
        }
    }

    // with linked joins, we need to enter state but should not notify.
    // state entries are needed to track join logic.
    if (!StateMachineUtils.isPseudoState(state, PseudoStateKind.JOIN)) {
        notifyStateEntered(
                buildStateContext(Stage.STATE_ENTRY, message, transition, getRelayStateMachine(), null, state));
    }
    log.debug("Enter state=[" + state + "]");
    state.entry(stateContext);
}